Gilad Chaplik has uploaded a new change for review.

Change subject: core: Move RunVm validation logic to RunVmCommand (1/X)
......................................................................

core: Move RunVm validation logic to RunVmCommand (1/X)

Curretly RunVm canDoAction logic is located both in the command and
in VmRunHandler.
This patch motivation is to concentrate all runVmCommand logic in a single 
place.

The validation logic is used also in prestarted vm pools feature.
RunVmCommandTest was changed appropriately.

Change-Id: Id4f65185ac3c3e2b6d65dd772268dbccaf9168a8
Signed-off-by: Gilad Chaplik <gchap...@redhat.com>
---
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RunVmCommand.java
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmPoolCommandBase.java
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmRunHandler.java
M 
backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/RunVmCommandTest.java
4 files changed, 331 insertions(+), 368 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/11/13111/1

diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RunVmCommand.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RunVmCommand.java
index 67cf737..cba41fb 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RunVmCommand.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RunVmCommand.java
@@ -2,11 +2,14 @@
 
 import java.io.File;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.Date;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 import java.util.Set;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -19,10 +22,14 @@
 import org.ovirt.engine.core.bll.quota.QuotaConsumptionParameter;
 import org.ovirt.engine.core.bll.quota.QuotaVdsDependent;
 import org.ovirt.engine.core.bll.quota.QuotaVdsGroupConsumptionParameter;
+import org.ovirt.engine.core.bll.storage.StoragePoolValidator;
 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.VmValidator;
 import org.ovirt.engine.core.common.AuditLogType;
 import org.ovirt.engine.core.common.FeatureSupported;
+import org.ovirt.engine.core.common.VdcActionUtils;
 import org.ovirt.engine.core.common.VdcObjectType;
 import org.ovirt.engine.core.common.action.CreateAllSnapshotsFromVmParameters;
 import org.ovirt.engine.core.common.action.RunVmParams;
@@ -31,6 +38,7 @@
 import org.ovirt.engine.core.common.businessentities.ActionGroup;
 import org.ovirt.engine.core.common.businessentities.BootSequence;
 import org.ovirt.engine.core.common.businessentities.Disk;
+import org.ovirt.engine.core.common.businessentities.DiskImage;
 import org.ovirt.engine.core.common.businessentities.DisplayType;
 import org.ovirt.engine.core.common.businessentities.Entities;
 import org.ovirt.engine.core.common.businessentities.FileTypeExtension;
@@ -40,24 +48,33 @@
 import org.ovirt.engine.core.common.businessentities.StorageDomainStatus;
 import org.ovirt.engine.core.common.businessentities.StorageDomainType;
 import org.ovirt.engine.core.common.businessentities.VDS;
+import org.ovirt.engine.core.common.businessentities.VDSStatus;
 import org.ovirt.engine.core.common.businessentities.VM;
 import org.ovirt.engine.core.common.businessentities.VMStatus;
+import org.ovirt.engine.core.common.businessentities.storage_pool;
 import org.ovirt.engine.core.common.businessentities.network.Network;
 import 
org.ovirt.engine.core.common.businessentities.network.VmNetworkInterface;
+import org.ovirt.engine.core.common.config.Config;
+import org.ovirt.engine.core.common.config.ConfigValues;
 import org.ovirt.engine.core.common.errors.VdcBLLException;
 import org.ovirt.engine.core.common.errors.VdcBllErrors;
 import org.ovirt.engine.core.common.job.Job;
 import org.ovirt.engine.core.common.job.Step;
 import org.ovirt.engine.core.common.job.StepEnum;
+import org.ovirt.engine.core.common.queries.GetAllIsoImagesListParameters;
+import org.ovirt.engine.core.common.queries.VdcQueryReturnValue;
+import org.ovirt.engine.core.common.queries.VdcQueryType;
 import org.ovirt.engine.core.common.utils.VmDeviceType;
 import org.ovirt.engine.core.common.vdscommands.CreateVmVDSCommandParameters;
 import org.ovirt.engine.core.common.vdscommands.IrsBaseVDSCommandParameters;
+import 
org.ovirt.engine.core.common.vdscommands.IsVmDuringInitiatingVDSCommandParameters;
 import org.ovirt.engine.core.common.vdscommands.ResumeVDSCommandParameters;
 import org.ovirt.engine.core.common.vdscommands.VDSCommandType;
 import org.ovirt.engine.core.common.vdscommands.VDSReturnValue;
 import org.ovirt.engine.core.compat.Guid;
 import org.ovirt.engine.core.compat.Version;
 import org.ovirt.engine.core.dal.VdcBllMessages;
+import org.ovirt.engine.core.dal.dbbroker.DbFacade;
 import org.ovirt.engine.core.dal.dbbroker.auditloghandling.AuditLogDirector;
 import org.ovirt.engine.core.dal.job.ExecutionMessageDirector;
 import org.ovirt.engine.core.utils.NetworkUtils;
@@ -517,7 +534,7 @@
             // Clear the first user:
             getVm().setConsoleUserId(null);
 
-            
getParameters().setRunAsStateless(getVmRunHandler().shouldVmRunAsStateless(getParameters(),
 getVm()));
+            
getParameters().setRunAsStateless(shouldVmRunAsStateless(getParameters(), 
getVm()));
 
             getVm().setDisplayType(getParameters().getUseVnc() == null ?
                     getVm().getDefaultDisplayType() :
@@ -663,38 +680,290 @@
             return 
failCanDoAction(VdcBllMessages.ACTION_TYPE_FAILED_VM_NOT_FOUND);
         }
 
+        // if VM is paused, it was already checked before that it is capable 
to run
         if (vm.getStatus() == VMStatus.Paused) {
-            // if VM is paused, it was already checked before that it is 
capable to run
             return true;
         }
-        else {
-            boolean canDoAction = canRunVm(vm) && validateNetworkInterfaces();
+        /********* VmRunHandler.canRunVm START **********/
 
-            // check for Vm Payload
-            if (canDoAction && getParameters().getVmPayload() != null) {
-                canDoAction = checkPayload(getParameters().getVmPayload(),
-                        getParameters().getDiskPath());
+        ArrayList<String> messages = getReturnValue().getCanDoActionMessages();
+        boolean canDoAction = true;
+        List<VmPropertiesUtils.ValidationError> validationErrors = 
getVmPropertiesUtils().validateVMProperties(
+                vm.getVdsGroupCompatibilityVersion(),
+                vm.getStaticData());
 
-                if (canDoAction && 
!StringUtils.isEmpty(getParameters().getFloppyPath()) &&
-                        getParameters().getVmPayload().getType() == 
VmDeviceType.FLOPPY) {
-                    
addCanDoActionMessage(VdcBllMessages.VMPAYLOAD_FLOPPY_EXCEEDED);
+        if (!validationErrors.isEmpty()) {
+            VmHandler.handleCustomPropertiesError(validationErrors, messages);
+            return false;
+        } else {
+            BootSequence boot_sequence = (getParameters().getBootSequence() != 
null) ?
+                    getParameters().getBootSequence() : 
vm.getDefaultBootSequence();
+            Guid storagePoolId = vm.getStoragePoolId();
+            // Block from running a VM with no HDD when its first boot device 
is
+            // HD and no other boot devices are configured
+            List<Disk> vmDisks = getVmRunHandler().getPluggedDisks(vm);
+            if (boot_sequence == BootSequence.C && vmDisks.size() == 0) {
+                String messageStr = !vmDisks.isEmpty() ?
+                        
VdcBllMessages.VM_CANNOT_RUN_FROM_DISK_WITHOUT_PLUGGED_DISK.toString() :
+                        
VdcBllMessages.VM_CANNOT_RUN_FROM_DISK_WITHOUT_DISK.toString();
+
+                messages.add(messageStr);
+                canDoAction = false;
+            } else {
+                // If CD appears as first and there is no ISO in storage
+                // pool/ISO inactive -
+                // you cannot run this VM
+
+                if (boot_sequence == BootSequence.CD && 
getVmRunHandler().findActiveISODomain(storagePoolId) == null) {
+                    
messages.add(VdcBllMessages.VM_CANNOT_RUN_FROM_CD_WITHOUT_ACTIVE_STORAGE_DOMAIN_ISO.toString());
                     canDoAction = false;
-                }
-                else {
-                    getVm().setVmPayload(getParameters().getVmPayload());
+                } else {
+                    // if there is network in the boot sequence, check that the
+                    // vm has network,
+                    // otherwise the vm cannot be run in vdsm
+                    if (boot_sequence == BootSequence.N
+                            && 
DbFacade.getInstance().getVmNetworkInterfaceDao().getAllForVm(vm.getId()).size()
 == 0) {
+                        
messages.add(VdcBllMessages.VM_CANNOT_RUN_FROM_NETWORK_WITHOUT_NETWORK.toString());
+                        canDoAction = false;
+                    }
+
+                    if (canDoAction) {
+                        ValidationResult vmNotLockedResult = new 
VmValidator(vm).vmNotLocked();
+                        if (!vmNotLockedResult.isValid()) {
+                            
messages.add(vmNotLockedResult.getMessage().name());
+                            canDoAction = false;
+                        }
+                    }
+
+                    if (canDoAction) {
+                        ValidationResult vmDuringSnapshotResult =
+                                
getSnapshotsValidator().vmNotDuringSnapshot(vm.getId());
+                        if (!vmDuringSnapshotResult.isValid()) {
+                            
messages.add(vmDuringSnapshotResult.getMessage().name());
+                            canDoAction = false;
+                        }
+                    }
+
+                    List<DiskImage> vmImages = 
ImagesHandler.filterImageDisks(vmDisks, true, false);
+                    if (canDoAction && !vmImages.isEmpty()) {
+                        storage_pool sp = 
getStoragePoolDAO().get(vm.getStoragePoolId());
+                        ValidationResult spUpResult = new 
StoragePoolValidator(sp).isUp();
+                        if (!spUpResult.isValid()) {
+                            messages.add(spUpResult.getMessage().name());
+                            canDoAction = false;
+                        }
+
+                        if (canDoAction) {
+                            canDoAction = performImageChecksForRunningVm(vm, 
messages, getParameters(), vmImages);
+                        }
+
+                        // Check if iso and floppy path exists
+                        if (canDoAction && !vm.isAutoStartup()
+                                && 
!validateIsoPath(getVmRunHandler().findActiveISODomain(vm.getStoragePoolId()),
+                                        getParameters(),
+                                        messages)) {
+                            canDoAction = false;
+                        } else if (canDoAction) {
+                            boolean isVmDuringInit = ((Boolean) getBackend()
+                                    .getResourceManager()
+                                    
.RunVdsCommand(VDSCommandType.IsVmDuringInitiating,
+                                            new 
IsVmDuringInitiatingVDSCommandParameters(vm.getId()))
+                                    .getReturnValue()).booleanValue();
+                            if (vm.isRunning() || (vm.getStatus() == 
VMStatus.NotResponding) || isVmDuringInit) {
+                                canDoAction = false;
+                                
messages.add(VdcBllMessages.ACTION_TYPE_FAILED_VM_IS_RUNNING.toString());
+                            } else if (vm.getStatus() == VMStatus.Paused && 
vm.getRunOnVds() != null) {
+                                VDS vds = 
DbFacade.getInstance().getVdsDao().get(
+                                        new Guid(vm.getRunOnVds().toString()));
+                                if (vds.getStatus() != VDSStatus.Up) {
+                                    canDoAction = false;
+                                    
messages.add(VdcBllMessages.VAR__HOST_STATUS__UP.toString());
+                                    
messages.add(VdcBllMessages.ACTION_TYPE_FAILED_VDS_STATUS_ILLEGAL.toString());
+                                }
+                            }
+
+                            boolean isStatelessVm = 
shouldVmRunAsStateless(getParameters(), vm);
+
+                            if (canDoAction && isStatelessVm
+                                    && 
!getSnapshotsValidator().vmNotInPreview(vm.getId()).isValid()) {
+                                canDoAction = false;
+                                
messages.add(VdcBllMessages.VM_CANNOT_RUN_STATELESS_WHILE_IN_PREVIEW.toString());
+                            }
+
+                            // if the VM itself is stateless or run once as 
stateless
+                            if (canDoAction && isStatelessVm && 
vm.isAutoStartup()) {
+                                canDoAction = false;
+                                
messages.add(VdcBllMessages.VM_CANNOT_RUN_STATELESS_HA.toString());
+                            }
+
+                            if (canDoAction && isStatelessVm && 
!hasSpaceForSnapshots(vm, messages)) {
+                                return false;
+                            }
+                        }
+                    }
+
+                    canDoAction =
+                            canDoAction == false ? canDoAction : 
getVdsSelector().canFindVdsToRunOn(messages, false);
+
+                    /**
+                     * only if can do action ok then check with actions matrix 
that status is valid for this
+                     * action
+                     */
+                    if (canDoAction
+                            && !VdcActionUtils.CanExecute(Arrays.asList(vm), 
VM.class,
+                                    VdcActionType.RunVm)) {
+                        canDoAction = false;
+                        
messages.add(VdcBllMessages.ACTION_TYPE_FAILED_VM_STATUS_ILLEGAL.toString());
+                    }
                 }
             }
-
-            return canDoAction;
         }
+
+        /********* VmRunHandler.canRunVm END **********/
+        canDoAction &= validateNetworkInterfaces();
+
+        // check for Vm Payload
+        if (canDoAction && getParameters().getVmPayload() != null) {
+            canDoAction = checkPayload(getParameters().getVmPayload(),
+                    getParameters().getDiskPath());
+
+            if (canDoAction && 
!StringUtils.isEmpty(getParameters().getFloppyPath()) &&
+                    getParameters().getVmPayload().getType() == 
VmDeviceType.FLOPPY) {
+                
addCanDoActionMessage(VdcBllMessages.VMPAYLOAD_FLOPPY_EXCEEDED);
+                canDoAction = false;
+            }
+            else {
+                getVm().setVmPayload(getParameters().getVmPayload());
+            }
+        }
+
+        return canDoAction;
     }
 
-    protected boolean canRunVm(VM vm) {
-        return getVmRunHandler().canRunVm(vm,
-                getReturnValue().getCanDoActionMessages(),
-                getParameters(),
-                getVdsSelector(),
-                getSnapshotsValidator(), getVmPropertiesUtils());
+    /**
+     * Check isValid, storageDomain and diskSpace only if VM is not HA VM
+     */
+    protected boolean performImageChecksForRunningVm
+            (VM vm, List<String> message, RunVmParams runParams, 
List<DiskImage> vmDisks) {
+        return ImagesHandler.PerformImagesChecks(message,
+                vm.getStoragePoolId(), Guid.Empty, !vm.isAutoStartup(),
+                true, false, false,
+                !vm.isAutoStartup() || !runParams.getIsInternal(),
+                !vm.isAutoStartup() || !runParams.getIsInternal(),
+                vmDisks);
+    }
+
+    @SuppressWarnings("unchecked")
+    private boolean validateIsoPath(Guid storageDomainId,
+            RunVmParams runParams,
+            ArrayList<String> messages) {
+        if (!StringUtils.isEmpty(runParams.getDiskPath())) {
+            if (storageDomainId == null) {
+                
messages.add(VdcBllMessages.VM_CANNOT_RUN_FROM_CD_WITHOUT_ACTIVE_STORAGE_DOMAIN_ISO.toString());
+                return false;
+            }
+            boolean retValForIso = false;
+            VdcQueryReturnValue ret =
+                    
getBackend().runInternalQuery(VdcQueryType.GetAllIsoImagesList,
+                            new 
GetAllIsoImagesListParameters(storageDomainId));
+            if (ret != null && ret.getReturnValue() != null && 
ret.getSucceeded()) {
+                List<RepoFileMetaData> repoFileNameList = 
(List<RepoFileMetaData>) ret.getReturnValue();
+                if (repoFileNameList != null) {
+                    for (RepoFileMetaData isoFileMetaData : 
(List<RepoFileMetaData>) ret.getReturnValue()) {
+                        if 
(isoFileMetaData.getRepoFileName().equals(runParams.getDiskPath())) {
+                            retValForIso = true;
+                            break;
+                        }
+                    }
+                }
+            }
+            if (!retValForIso) {
+                
messages.add(VdcBllMessages.ERROR_CANNOT_FIND_ISO_IMAGE_PATH.toString());
+                return false;
+            }
+        }
+
+        if (!StringUtils.isEmpty(runParams.getFloppyPath())) {
+            boolean retValForFloppy = false;
+            VdcQueryReturnValue ret =
+                    
getBackend().runInternalQuery(VdcQueryType.GetAllFloppyImagesList,
+                            new 
GetAllIsoImagesListParameters(storageDomainId));
+            if (ret != null && ret.getReturnValue() != null && 
ret.getSucceeded()) {
+                List<RepoFileMetaData> repoFileNameList = 
(List<RepoFileMetaData>) ret.getReturnValue();
+                if (repoFileNameList != null) {
+
+                    for (RepoFileMetaData isoFileMetaData : 
(List<RepoFileMetaData>) ret.getReturnValue()) {
+                        if 
(isoFileMetaData.getRepoFileName().equals(runParams.getFloppyPath())) {
+                            retValForFloppy = true;
+                            break;
+                        }
+                    }
+                }
+            }
+            if (!retValForFloppy) {
+                
messages.add(VdcBllMessages.ERROR_CANNOT_FIND_FLOPPY_IMAGE_PATH.toString());
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    private boolean shouldVmRunAsStateless(RunVmParams param, VM vm) {
+        if (param.getRunAsStateless() != null) {
+            return param.getRunAsStateless();
+        }
+        return vm.isStateless();
+    }
+
+    /**
+     * check that we can create snapshots for all disks
+     *
+     * @param vm
+     * @return true if all storage domains have enough space to create 
snapshots for this VM plugged disks
+     */
+    private boolean hasSpaceForSnapshots(VM vm, ArrayList<String> message) {
+        Integer minSnapshotSize = Config.<Integer> 
GetValue(ConfigValues.InitStorageSparseSizeInGB);
+        for (Entry<StorageDomain, Integer> e : 
mapStorageDomainsToNumOfDisks(vm).entrySet()) {
+            if (!destinationHasSpace(e.getKey(), minSnapshotSize * 
e.getValue(), message)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private boolean destinationHasSpace(StorageDomain storageDomain, long 
sizeRequested, ArrayList<String> message) {
+        return validate(new 
StorageDomainValidator(storageDomain).isDomainHasSpaceForRequest(sizeRequested),
 message);
+    }
+
+    private boolean validate(ValidationResult validationResult, 
ArrayList<String> message) {
+        if (!validationResult.isValid()) {
+            message.add(validationResult.getMessage().name());
+            if (validationResult.getVariableReplacements() != null) {
+                for (String variableReplacement : 
validationResult.getVariableReplacements()) {
+                    message.add(variableReplacement);
+                }
+            }
+        }
+        return validationResult.isValid();
+    }
+
+    /**
+     * map the VM number of pluggable and snapable disks from their domain.
+     *
+     * @param vm
+     * @return
+     */
+    private Map<StorageDomain, Integer> mapStorageDomainsToNumOfDisks(VM vm) {
+        Map<StorageDomain, Integer> map = new HashMap<StorageDomain, 
Integer>();
+        for (Disk disk : getVmRunHandler().getPluggedDisks(vm)) {
+            if (disk.isAllowSnapshot()) {
+                for (StorageDomain domain : 
getStorageDomainDAO().getAllStorageDomainsByImageId(((DiskImage) 
disk).getImageId())) {
+                    map.put(domain, map.containsKey(domain) ? 
Integer.valueOf(map.get(domain) + 1) : Integer.valueOf(1));
+                }
+            }
+        }
+        return map;
     }
 
     protected VmPropertiesUtils getVmPropertiesUtils() {
@@ -783,7 +1052,7 @@
     /**
      * @return true if all VM network interfaces are valid
      */
-    private boolean validateNetworkInterfaces() {
+    protected boolean validateNetworkInterfaces() {
         Map<String, VmNetworkInterface> interfaceNetworkMap = 
Entities.interfacesByNetworkName(getVm().getInterfaces());
         Set<String> interfaceNetworkNames = interfaceNetworkMap.keySet();
         List<Network> clusterNetworks = 
getNetworkDAO().getAllForCluster(getVm().getVdsGroupId());
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmPoolCommandBase.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmPoolCommandBase.java
index 9220603..38effeb 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmPoolCommandBase.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmPoolCommandBase.java
@@ -266,12 +266,10 @@
                         true,
                         new VdsFreeMemoryChecker(new NonWaitingDelayer()));
 
-        return VmRunHandler.getInstance().canRunVm(vm,
-                messages,
-                runVmParams,
-                vdsSelector,
-                new SnapshotsValidator(),
-                getVmPropertiesUtils());
+        // TODO: temporary until this logic will be extracted.
+        RunVmCommand<RunVmParams> runVmCommand = new 
RunVmCommand<RunVmParams>(runVmParams);
+        runVmCommand.getReturnValue().setCanDoActionMessages(messages);
+        return runVmCommand.canDoAction();
     }
 
     protected static VmPropertiesUtils getVmPropertiesUtils() {
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmRunHandler.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmRunHandler.java
index 273ad02..bb48440 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmRunHandler.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmRunHandler.java
@@ -1,52 +1,22 @@
 package org.ovirt.engine.core.bll;
 
 import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
 
-import org.apache.commons.lang.StringUtils;
-import org.ovirt.engine.core.bll.interfaces.BackendInternal;
-import org.ovirt.engine.core.bll.snapshots.SnapshotsValidator;
-import org.ovirt.engine.core.bll.storage.StoragePoolValidator;
-import org.ovirt.engine.core.bll.validator.StorageDomainValidator;
-import org.ovirt.engine.core.bll.validator.VmValidator;
-import org.ovirt.engine.core.common.VdcActionUtils;
-import org.ovirt.engine.core.common.action.RunVmParams;
-import org.ovirt.engine.core.common.action.VdcActionType;
-import org.ovirt.engine.core.common.businessentities.BootSequence;
 import org.ovirt.engine.core.common.businessentities.Disk;
-import org.ovirt.engine.core.common.businessentities.DiskImage;
-import org.ovirt.engine.core.common.businessentities.RepoFileMetaData;
 import org.ovirt.engine.core.common.businessentities.StorageDomain;
 import org.ovirt.engine.core.common.businessentities.StorageDomainStatus;
 import org.ovirt.engine.core.common.businessentities.StorageDomainType;
-import org.ovirt.engine.core.common.businessentities.VDS;
-import org.ovirt.engine.core.common.businessentities.VDSStatus;
 import org.ovirt.engine.core.common.businessentities.VM;
-import org.ovirt.engine.core.common.businessentities.VMStatus;
 import org.ovirt.engine.core.common.businessentities.VmDevice;
-import org.ovirt.engine.core.common.businessentities.storage_pool;
-import org.ovirt.engine.core.common.config.Config;
-import org.ovirt.engine.core.common.config.ConfigValues;
-import org.ovirt.engine.core.common.queries.GetAllIsoImagesListParameters;
-import org.ovirt.engine.core.common.queries.VdcQueryReturnValue;
-import org.ovirt.engine.core.common.queries.VdcQueryType;
 import org.ovirt.engine.core.common.utils.VmDeviceType;
-import 
org.ovirt.engine.core.common.vdscommands.IsVmDuringInitiatingVDSCommandParameters;
-import org.ovirt.engine.core.common.vdscommands.VDSCommandType;
 import org.ovirt.engine.core.compat.Guid;
-import org.ovirt.engine.core.dal.VdcBllMessages;
 import org.ovirt.engine.core.dal.dbbroker.DbFacade;
 import org.ovirt.engine.core.dao.DiskDao;
 import org.ovirt.engine.core.dao.StorageDomainDAO;
-import org.ovirt.engine.core.dao.StoragePoolDAO;
 import org.ovirt.engine.core.dao.VmDeviceDAO;
 import org.ovirt.engine.core.utils.log.Log;
 import org.ovirt.engine.core.utils.log.LogFactory;
-import org.ovirt.engine.core.utils.vmproperties.VmPropertiesUtils;
 
 /** A utility class for verifying running a vm*/
 public class VmRunHandler {
@@ -55,215 +25,6 @@
 
     public static VmRunHandler getInstance() {
         return instance;
-    }
-
-    /**
-     * This method checks whether the given VM is capable to run.
-     *
-     * @param vm not null {@link VM}
-     * @param message
-     * @param runParams
-     * @param vdsSelector
-     * @param snapshotsValidator
-     * @param vmPropsUtils
-     * @return true if the given VM can run with the given properties, false 
otherwise
-     */
-    public boolean canRunVm(VM vm, ArrayList<String> message, RunVmParams 
runParams,
-            VdsSelector vdsSelector, SnapshotsValidator snapshotsValidator, 
VmPropertiesUtils vmPropsUtils) {
-        boolean retValue = true;
-
-        List<VmPropertiesUtils.ValidationError> validationErrors = 
vmPropsUtils.validateVMProperties(
-                vm.getVdsGroupCompatibilityVersion(),
-                vm.getStaticData());
-
-        if (!validationErrors.isEmpty()) {
-            VmHandler.handleCustomPropertiesError(validationErrors, message);
-            retValue = false;
-        } else {
-            BootSequence boot_sequence = (runParams.getBootSequence() != null) 
?
-                    runParams.getBootSequence() : vm.getDefaultBootSequence();
-            Guid storagePoolId = vm.getStoragePoolId();
-            // Block from running a VM with no HDD when its first boot device 
is
-            // HD and no other boot devices are configured
-            List<Disk> vmDisks = getPluggedDisks(vm);
-            if (boot_sequence == BootSequence.C && vmDisks.size() == 0) {
-                String messageStr = !vmDisks.isEmpty() ?
-                        
VdcBllMessages.VM_CANNOT_RUN_FROM_DISK_WITHOUT_PLUGGED_DISK.toString() :
-                        
VdcBllMessages.VM_CANNOT_RUN_FROM_DISK_WITHOUT_DISK.toString();
-
-                message.add(messageStr);
-                retValue = false;
-            } else {
-                // If CD appears as first and there is no ISO in storage
-                // pool/ISO inactive -
-                // you cannot run this VM
-
-                if (boot_sequence == BootSequence.CD && 
findActiveISODomain(storagePoolId) == null) {
-                    
message.add(VdcBllMessages.VM_CANNOT_RUN_FROM_CD_WITHOUT_ACTIVE_STORAGE_DOMAIN_ISO.toString());
-                    retValue = false;
-                } else {
-                    // if there is network in the boot sequence, check that the
-                    // vm has network,
-                    // otherwise the vm cannot be run in vdsm
-                    if (boot_sequence == BootSequence.N
-                            && 
DbFacade.getInstance().getVmNetworkInterfaceDao().getAllForVm(vm.getId()).size()
 == 0) {
-                        
message.add(VdcBllMessages.VM_CANNOT_RUN_FROM_NETWORK_WITHOUT_NETWORK.toString());
-                        retValue = false;
-                    }
-
-                    if (retValue) {
-                        ValidationResult vmNotLockedResult = new 
VmValidator(vm).vmNotLocked();
-                        if (!vmNotLockedResult.isValid()) {
-                            message.add(vmNotLockedResult.getMessage().name());
-                            retValue = false;
-                        }
-                    }
-
-                    if (retValue) {
-                        ValidationResult vmDuringSnapshotResult =
-                                
snapshotsValidator.vmNotDuringSnapshot(vm.getId());
-                        if (!vmDuringSnapshotResult.isValid()) {
-                            
message.add(vmDuringSnapshotResult.getMessage().name());
-                            retValue = false;
-                        }
-                    }
-
-                    List<DiskImage> vmImages = 
ImagesHandler.filterImageDisks(vmDisks, true, false);
-                    if (retValue && !vmImages.isEmpty()) {
-                        storage_pool sp = 
getStoragePoolDAO().get(vm.getStoragePoolId());
-                        ValidationResult spUpResult = new 
StoragePoolValidator(sp).isUp();
-                        if (!spUpResult.isValid()) {
-                            message.add(spUpResult.getMessage().name());
-                            retValue = false;
-                        }
-
-                        if (retValue) {
-                            retValue = performImageChecksForRunningVm(vm, 
message, runParams, vmImages);
-                        }
-
-                        // Check if iso and floppy path exists
-                        if (retValue && !vm.isAutoStartup()
-                                && 
!validateIsoPath(findActiveISODomain(vm.getStoragePoolId()),
-                                        runParams,
-                                        message)) {
-                            retValue = false;
-                        } else if (retValue) {
-                            boolean isVmDuringInit = ((Boolean) getBackend()
-                                    .getResourceManager()
-                                    
.RunVdsCommand(VDSCommandType.IsVmDuringInitiating,
-                                            new 
IsVmDuringInitiatingVDSCommandParameters(vm.getId()))
-                                    .getReturnValue()).booleanValue();
-                            if (vm.isRunning() || (vm.getStatus() == 
VMStatus.NotResponding) || isVmDuringInit) {
-                                retValue = false;
-                                
message.add(VdcBllMessages.ACTION_TYPE_FAILED_VM_IS_RUNNING.toString());
-                            } else if (vm.getStatus() == VMStatus.Paused && 
vm.getRunOnVds() != null) {
-                                VDS vds = 
DbFacade.getInstance().getVdsDao().get(
-                                        new Guid(vm.getRunOnVds().toString()));
-                                if (vds.getStatus() != VDSStatus.Up) {
-                                    retValue = false;
-                                    
message.add(VdcBllMessages.VAR__HOST_STATUS__UP.toString());
-                                    
message.add(VdcBllMessages.ACTION_TYPE_FAILED_VDS_STATUS_ILLEGAL.toString());
-                                }
-                            }
-
-                            boolean isStatelessVm = 
shouldVmRunAsStateless(runParams, vm);
-
-                            if (retValue && isStatelessVm && 
!snapshotsValidator.vmNotInPreview(vm.getId()).isValid()) {
-                                retValue = false;
-                                
message.add(VdcBllMessages.VM_CANNOT_RUN_STATELESS_WHILE_IN_PREVIEW.toString());
-                            }
-
-                            // if the VM itself is stateless or run once as 
stateless
-                            if (retValue && isStatelessVm && 
vm.isAutoStartup()) {
-                                retValue = false;
-                                
message.add(VdcBllMessages.VM_CANNOT_RUN_STATELESS_HA.toString());
-                            }
-
-                            if (retValue && isStatelessVm && 
!hasSpaceForSnapshots(vm, message)) {
-                                return false;
-                            }
-                        }
-                    }
-
-                    retValue = retValue == false ? retValue : 
vdsSelector.canFindVdsToRunOn(message, false);
-
-                    /**
-                     * only if can do action ok then check with actions matrix 
that status is valid for this
-                     * action
-                     */
-                    if (retValue
-                            && !VdcActionUtils.CanExecute(Arrays.asList(vm), 
VM.class,
-                                    VdcActionType.RunVm)) {
-                        retValue = false;
-                        
message.add(VdcBllMessages.ACTION_TYPE_FAILED_VM_STATUS_ILLEGAL.toString());
-                    }
-                }
-            }
-        }
-        return retValue;
-    }
-
-    /**
-     * check that we can create snapshots for all disks
-     *
-     * @param vm
-     * @return true if all storage domains have enough space to create 
snapshots for this VM plugged disks
-     */
-    public boolean hasSpaceForSnapshots(VM vm, ArrayList<String> message) {
-        Integer minSnapshotSize = Config.<Integer> 
GetValue(ConfigValues.InitStorageSparseSizeInGB);
-        for (Entry<StorageDomain, Integer> e : 
mapStorageDomainsToNumOfDisks(vm).entrySet()) {
-            if (!destinationHasSpace(e.getKey(), minSnapshotSize * 
e.getValue(), message)) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    private boolean destinationHasSpace(StorageDomain storageDomain, long 
sizeRequested, ArrayList<String> message) {
-        return validate(new 
StorageDomainValidator(storageDomain).isDomainHasSpaceForRequest(sizeRequested),
 message);
-    }
-
-    protected boolean validate(ValidationResult validationResult, 
ArrayList<String> message) {
-        if (!validationResult.isValid()) {
-            message.add(validationResult.getMessage().name());
-            if (validationResult.getVariableReplacements() != null) {
-                for (String variableReplacement : 
validationResult.getVariableReplacements()) {
-                    message.add(variableReplacement);
-                }
-            }
-        }
-        return validationResult.isValid();
-    }
-
-    /**
-     * map the VM number of pluggable and snapable disks from their domain.
-     *
-     * @param vm
-     * @return
-     */
-    public Map<StorageDomain, Integer> mapStorageDomainsToNumOfDisks(VM vm) {
-        Map<StorageDomain, Integer> map = new HashMap<StorageDomain, 
Integer>();
-        for (Disk disk : getPluggedDisks(vm)) {
-            if (disk.isAllowSnapshot()) {
-                for (StorageDomain domain : 
getStorageDomainDAO().getAllStorageDomainsByImageId(((DiskImage) 
disk).getImageId())) {
-                    map.put(domain, map.containsKey(domain) ? 
Integer.valueOf(map.get(domain) + 1) : Integer.valueOf(1));
-                }
-            }
-        }
-        return map;
-    }
-
-    /**
-     * Check isValid, storageDomain and diskSpace only if VM is not HA VM
-     */
-    protected boolean performImageChecksForRunningVm
-            (VM vm, List<String> message, RunVmParams runParams, 
List<DiskImage> vmDisks) {
-        return ImagesHandler.PerformImagesChecks(message,
-                vm.getStoragePoolId(), Guid.Empty, !vm.isAutoStartup(),
-                true, false, false,
-                !vm.isAutoStartup() || !runParams.getIsInternal(),
-                !vm.isAutoStartup() || !runParams.getIsInternal(),
-                vmDisks);
     }
 
     /**
@@ -315,73 +76,6 @@
         return isoGuid;
     }
 
-    @SuppressWarnings("unchecked")
-    private boolean validateIsoPath(Guid storageDomainId,
-            RunVmParams runParams,
-            ArrayList<String> messages) {
-        if (!StringUtils.isEmpty(runParams.getDiskPath())) {
-            if (storageDomainId == null) {
-                
messages.add(VdcBllMessages.VM_CANNOT_RUN_FROM_CD_WITHOUT_ACTIVE_STORAGE_DOMAIN_ISO.toString());
-                return false;
-            }
-            boolean retValForIso = false;
-            VdcQueryReturnValue ret =
-                    
getBackend().runInternalQuery(VdcQueryType.GetAllIsoImagesList,
-                            new 
GetAllIsoImagesListParameters(storageDomainId));
-            if (ret != null && ret.getReturnValue() != null && 
ret.getSucceeded()) {
-                List<RepoFileMetaData> repoFileNameList = 
(List<RepoFileMetaData>) ret.getReturnValue();
-                if (repoFileNameList != null) {
-                    for (RepoFileMetaData isoFileMetaData : 
(List<RepoFileMetaData>) ret.getReturnValue()) {
-                        if 
(isoFileMetaData.getRepoFileName().equals(runParams.getDiskPath())) {
-                            retValForIso = true;
-                            break;
-                        }
-                    }
-                }
-            }
-            if (!retValForIso) {
-                
messages.add(VdcBllMessages.ERROR_CANNOT_FIND_ISO_IMAGE_PATH.toString());
-                return false;
-            }
-        }
-
-        if (!StringUtils.isEmpty(runParams.getFloppyPath())) {
-            boolean retValForFloppy = false;
-            VdcQueryReturnValue ret =
-                    
getBackend().runInternalQuery(VdcQueryType.GetAllFloppyImagesList,
-                            new 
GetAllIsoImagesListParameters(storageDomainId));
-            if (ret != null && ret.getReturnValue() != null && 
ret.getSucceeded()) {
-                List<RepoFileMetaData> repoFileNameList = 
(List<RepoFileMetaData>) ret.getReturnValue();
-                if (repoFileNameList != null) {
-
-                    for (RepoFileMetaData isoFileMetaData : 
(List<RepoFileMetaData>) ret.getReturnValue()) {
-                        if 
(isoFileMetaData.getRepoFileName().equals(runParams.getFloppyPath())) {
-                            retValForFloppy = true;
-                            break;
-                        }
-                    }
-                }
-            }
-            if (!retValForFloppy) {
-                
messages.add(VdcBllMessages.ERROR_CANNOT_FIND_FLOPPY_IMAGE_PATH.toString());
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    public boolean shouldVmRunAsStateless(RunVmParams param, VM vm) {
-        if (param.getRunAsStateless() != null) {
-            return param.getRunAsStateless();
-        }
-        return vm.isStateless();
-    }
-
-    protected BackendInternal getBackend() {
-        return Backend.getInstance();
-    }
-
     protected DiskDao getDiskDao() {
         return DbFacade.getInstance().getDiskDao();
     }
@@ -394,7 +88,4 @@
         return DbFacade.getInstance().getStorageDomainDao();
     }
 
-    protected StoragePoolDAO getStoragePoolDAO() {
-        return DbFacade.getInstance().getStoragePoolDao();
-    }
 }
diff --git 
a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/RunVmCommandTest.java
 
b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/RunVmCommandTest.java
index 802998c..e60ac94 100644
--- 
a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/RunVmCommandTest.java
+++ 
b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/RunVmCommandTest.java
@@ -36,13 +36,13 @@
 import org.ovirt.engine.core.common.businessentities.Disk;
 import org.ovirt.engine.core.common.businessentities.DiskImage;
 import org.ovirt.engine.core.common.businessentities.IVdsAsyncCommand;
+import org.ovirt.engine.core.common.businessentities.StorageDomain;
 import org.ovirt.engine.core.common.businessentities.StoragePoolStatus;
 import org.ovirt.engine.core.common.businessentities.VM;
 import org.ovirt.engine.core.common.businessentities.VMStatus;
 import org.ovirt.engine.core.common.businessentities.VmDevice;
 import org.ovirt.engine.core.common.businessentities.VmDeviceId;
 import org.ovirt.engine.core.common.businessentities.VmStatic;
-import org.ovirt.engine.core.common.businessentities.StorageDomain;
 import org.ovirt.engine.core.common.businessentities.storage_pool;
 import org.ovirt.engine.core.common.config.ConfigValues;
 import org.ovirt.engine.core.common.interfaces.VDSBrokerFrontend;
@@ -100,7 +100,6 @@
 
     public void mockBackend() {
         doReturn(backend).when(command).getBackend();
-        doReturn(backend).when(vmRunHandler).getBackend();
 
         VDSReturnValue vdsReturnValue = new VDSReturnValue();
         vdsReturnValue.setReturnValue(true);
@@ -291,7 +290,7 @@
     }
 
     private VM createVmForTesting(String initrd, String kernel) {
-        mockVm(command);
+        mockVm();
 
         // Set parameter
         command.getVm().setInitrdUrl(initrd);
@@ -304,50 +303,55 @@
     }
 
     /**
-     * Mock a VM.
+     * Mock a VM with status.
      */
-    private VM mockVm(RunVmCommand<RunVmParams> spyVmCommand) {
+    private VM mockVm(VMStatus status) {
         VM vm = new VM();
-        vm.setStatus(VMStatus.Down);
+        vm.setStatus(status);
+        vm.setVdsGroupId(new Guid());
         doReturn(vmDAO).when(command).getVmDAO();
         when(vmDAO.get(command.getParameters().getVmId())).thenReturn(vm);
         return vm;
+    }
+
+    /**
+     * Mock a VM.
+     */
+    private VM mockVm() {
+        return mockVm(VMStatus.Down);
     }
 
     @Before
     public void createCommand() {
         RunVmParams param = new RunVmParams(Guid.NewGuid());
         command = spy(new RunVmCommand<RunVmParams>(param));
-
-        mockVmRunHandler();
-        mockSuccessfulSnapshotValidator();
-        mockVmPropertiesUtils();
-        mockBackend();
-    }
-
-    protected void mockVmRunHandler() {
-        storage_pool sp = new storage_pool();
-        sp.setstatus(StoragePoolStatus.Up);
-        when(spDao.get(any(Guid.class))).thenReturn(sp);
-        doReturn(spDao).when(vmRunHandler).getStoragePoolDAO();
-
-        doReturn(vmRunHandler).when(command).getVmRunHandler();
-
-        
doReturn(true).when(vmRunHandler).performImageChecksForRunningVm(any(VM.class),
+        doReturn(true).when(command).validateNetworkInterfaces();
+        
doReturn(true).when(command).performImageChecksForRunningVm(any(VM.class),
                 anyListOf(String.class),
                 any(RunVmParams.class),
                 anyListOf(DiskImage.class));
+
+        doReturn(spDao).when(command).getStoragePoolDAO();
+        storage_pool sp = new storage_pool();
+        sp.setstatus(StoragePoolStatus.Up);
+        when(spDao.get(any(Guid.class))).thenReturn(sp);
+
+        doReturn(vmRunHandler).when(command).getVmRunHandler();
+
+        mockSuccessfulSnapshotValidator();
+        mockVmPropertiesUtils();
+        mockBackend();
     }
 
     @Test
     public void canRunVmFailNodisk() {
         initDAOMocks(Collections.<Disk> emptyList(), Collections.<VmDevice> 
emptyList());
 
-        final VM vm = new VM();
+        final VM vm = mockVm();
         doReturn(new VdsSelector(vm, new Guid(), true, new 
VdsFreeMemoryChecker(command))).when(command)
                 .getVdsSelector();
 
-        assertFalse(command.canRunVm(vm));
+        assertFalse(command.canDoAction());
         
assertTrue(command.getReturnValue().getCanDoActionMessages().contains("VM_CANNOT_RUN_FROM_DISK_WITHOUT_DISK"));
     }
 
@@ -358,13 +362,14 @@
         disks.add(diskImage);
         final VmDevice vmDevice = createDiskVmDevice(diskImage);
         initDAOMocks(disks, Collections.singletonList(vmDevice));
-        final VM vm = new VM();
+        final VM vm = mockVm(VMStatus.Up);
         vm.setStatus(VMStatus.Up);
         vm.setStoragePoolId(Guid.NewGuid());
+
         doReturn(new VdsSelector(vm, new NGuid(), true, new 
VdsFreeMemoryChecker(command))).when(command)
                 .getVdsSelector();
 
-        assertFalse(command.canRunVm(vm));
+        assertFalse(command.canDoAction());
         
assertTrue(command.getReturnValue().getCanDoActionMessages().contains("ACTION_TYPE_FAILED_VM_IS_RUNNING"));
     }
 
@@ -375,13 +380,13 @@
         disks.add(diskImage);
         final VmDevice vmDevice = createDiskVmDevice(diskImage);
         initDAOMocks(disks, Collections.singletonList(vmDevice));
-        final VM vm = new VM();
+        final VM vm = mockVm();
         SnapshotsValidator snapshotsValidator = mock(SnapshotsValidator.class);
         when(snapshotsValidator.vmNotDuringSnapshot(vm.getId()))
                 .thenReturn(new 
ValidationResult(VdcBllMessages.ACTION_TYPE_FAILED_VM_IS_DURING_SNAPSHOT));
         doReturn(snapshotsValidator).when(command).getSnapshotsValidator();
 
-        assertFalse(command.canRunVm(vm));
+        assertFalse(command.canDoAction());
         assertTrue(command.getReturnValue()
                 .getCanDoActionMessages()
                 
.contains(VdcBllMessages.ACTION_TYPE_FAILED_VM_IS_DURING_SNAPSHOT.name()));
@@ -405,13 +410,13 @@
         
when(vdsBrokerFrontend.RunVdsCommand(eq(VDSCommandType.IsVmDuringInitiating), 
any(VDSParametersBase.class))).thenReturn(vdsReturnValue);
         initDAOMocks(disks, Collections.singletonList(vmDevice));
 
-        final VM vm = new VM();
+        final VM vm = mockVm();
         // set stateless and HA
         vm.setStateless(isVmStateless);
         vm.setAutoStartup(autoStartUp);
 
         command.getParameters().setRunAsStateless(isStatelessParam);
-        boolean canRunVm = command.canRunVm(vm);
+        boolean canRunVm = command.canDoAction();
 
         final List<String> messages = 
command.getReturnValue().getCanDoActionMessages();
         assertEquals(shouldPass, canRunVm);


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

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

Reply via email to