use of org.ovirt.engine.core.bll.validator.MultipleVmsValidator in project ovirt-engine by oVirt.
the class MaintenanceNumberOfVdssCommand method validate.
@Override
protected boolean validate() {
boolean result = true;
Map<Guid, Cluster> clusters = new HashMap<>();
Set<Guid> clustersAsSet = new HashSet<>();
Set<Guid> vdsWithRunningVMs = new HashSet<>();
List<String> hostNotRespondingList = new ArrayList<>();
List<String> hostsWithNonMigratableVms = new ArrayList<>();
List<String> hostsWithVmsWithPluggedDiskSnapshots = new ArrayList<>();
List<String> nonMigratableVms = new ArrayList<>();
for (Guid vdsId : getParameters().getVdsIdList()) {
VDS vds = vdsDao.get(vdsId);
if (vds == null) {
log.error("ResourceManager::vdsMaintenance could not find VDS '{}'", vdsId);
result = failValidation(EngineMessage.VDS_INVALID_SERVER_ID);
continue;
}
// TODO make a more efficient call but normally the command just loads one cluster anyway
if (!clusters.containsKey(vds.getClusterId())) {
final Cluster cluster = clusterDao.get(vds.getClusterId());
clusters.put(cluster.getId(), cluster);
}
if (!vdssToMaintenance.containsKey(vdsId)) {
vdssToMaintenance.put(vdsId, vds);
if (vds.getSpmStatus() == VdsSpmStatus.SPM) {
addSharedLockEntry(vds);
}
}
if (getParameters().isStopGlusterService() && !vds.getClusterSupportsGlusterService()) {
result = failValidation(EngineMessage.ACTION_TYPE_FAILED_GLUSTER_SERVICE_MAINTENANCE_NOT_SUPPORTED_FOR_CLUSTER);
break;
}
}
result = result && acquireLockInternal();
if (result) {
// tasks running
for (Guid vdsId : getParameters().getVdsIdList()) {
VDS vds = vdssToMaintenance.get(vdsId);
if (vds != null) {
if ((vds.getStatus() != VDSStatus.Maintenance) && (vds.getStatus() != VDSStatus.NonResponsive) && (vds.getStatus() != VDSStatus.Up) && (vds.getStatus() != VDSStatus.Error) && (vds.getStatus() != VDSStatus.PreparingForMaintenance) && (vds.getStatus() != VDSStatus.Down) && (vds.getStatus() != VDSStatus.NonOperational && (vds.getStatus() != VDSStatus.InstallFailed))) {
result = failValidation(EngineMessage.VDS_CANNOT_MAINTENANCE_VDS_IS_NOT_OPERATIONAL);
} else {
List<VM> vms = vmDao.getAllRunningForVds(vdsId);
if (!vms.isEmpty()) {
vdsWithRunningVMs.add(vdsId);
}
clustersAsSet.add(vds.getClusterId());
List<String> nonMigratableVmDescriptionsToFrontEnd = new ArrayList<>();
for (VM vm : vms) {
// And they need safe place for migration
if (vm.isHostedEngine()) {
List<VDS> clusterVdses = vdsDao.getAllForClusterWithStatus(vds.getClusterId(), VDSStatus.Up);
if (!HostedEngineHelper.haveHostsAvailableforHE(clusterVdses, getParameters().getVdsIdList())) {
failValidation(EngineMessage.VDS_CANNOT_MAINTENANCE_NO_ALTERNATE_HOST_FOR_HOSTED_ENGINE);
return false;
}
}
// other non-migratable VMs are reported
if (vm.getMigrationSupport() != MigrationSupport.MIGRATABLE && !vm.isHostedEngine()) {
nonMigratableVmDescriptionsToFrontEnd.add(vm.getName());
}
}
List<AsyncTask> asyncTasks = null;
if (nonMigratableVmDescriptionsToFrontEnd.size() > 0) {
hostsWithNonMigratableVms.add(vds.getName());
nonMigratableVms.addAll(nonMigratableVmDescriptionsToFrontEnd);
// The non migratable VM names will be comma separated
log.error("VDS '{}' contains non migratable VMs", vdsId);
result = false;
} else if (!validate(new MultipleVmsValidator(vms).vmNotHavingPluggedDiskSnapshots(EngineMessage.VDS_CANNOT_MAINTENANCE_VM_HAS_PLUGGED_DISK_SNAPSHOT))) {
hostsWithVmsWithPluggedDiskSnapshots.add(vds.getName());
result = false;
} else if (vds.getStatus() == VDSStatus.Maintenance) {
result = failValidation(EngineMessage.VDS_CANNOT_MAINTENANCE_VDS_IS_IN_MAINTENANCE);
} else if (vds.getSpmStatus() == VdsSpmStatus.Contending) {
result = failValidation(EngineMessage.VDS_CANNOT_MAINTENANCE_SPM_CONTENDING);
} else if (vds.getStatus() == VDSStatus.NonResponsive && vds.getVmCount() > 0) {
result = false;
hostNotRespondingList.add(vds.getName());
} else if (vds.getStatus() == VDSStatus.NonResponsive && vds.getSpmStatus() != VdsSpmStatus.None) {
result = failValidation(EngineMessage.VDS_CANNOT_MAINTENANCE_VDS_IS_NOT_RESPONDING_AND_IS_SPM);
} else if (vds.getSpmStatus() == VdsSpmStatus.SPM && vds.getStatus() == VDSStatus.Up && ((asyncTasks = asyncTaskDao.getAsyncTaskIdsByStoragePoolId(vds.getStoragePoolId()))).size() > 0) {
String runningTasks = asyncTasks.stream().map(AsyncTask::toString).collect(Collectors.joining("\n"));
log.warn("There are running tasks on the SPM: '{}'", runningTasks);
result = failValidation(EngineMessage.VDS_CANNOT_MAINTENANCE_SPM_WITH_RUNNING_TASKS);
} else if (!validateNoRunningJobs(vds)) {
result = false;
} else if (!validateNoActiveImageTransfers(vds)) {
result = false;
} else if (!clusters.get(vds.getClusterId()).isInUpgradeMode()) {
result = handlePositiveEnforcingAffinityGroup(vdsId, vms);
}
}
}
}
// If one of the host is non responsive with running VM's, add a Validate message.
handleNonResponsiveHosts(hostNotRespondingList);
// If one of the vms is non migratable, add a Validate message.
handleNonMigratableVms(hostsWithNonMigratableVms, nonMigratableVms);
handleHostsWithVmsWithPluggedDiskSnapshots(hostsWithVmsWithPluggedDiskSnapshots);
if (result) {
// Remove all redundant clusters in clusters list, by adding it to a
// set.
// For each cluster check for each host that belongs to it, if its a
// part of the parameters and
// if there are running hosts for it - if it is up and is not in the
// parameters -migration will be possible
// to be performed, and there is no point to continue the check for
// the given cluster - otherwise,
// if the host is up and in the parameters - it may be that the
// cluster is problematic (no hosts in up
// state that we will be able to migrate VMs to)
// In the end - if the clusters list is not empty - this is an
// error, use the "problematic clusters list" to format an error to
// the client
List<String> problematicClusters = new ArrayList<>();
List<String> allHostsWithRunningVms = new ArrayList<>();
for (Guid clusterID : clustersAsSet) {
List<VDS> vdsList = vdsDao.getAllForCluster(clusterID);
boolean vdsForMigrationExists = checkIfThereIsVDSToHoldMigratedVMs(getParameters().getVdsIdList(), vdsList);
if (!vdsForMigrationExists) {
List<String> candidateHostsWithRunningVms = new ArrayList<>();
for (VDS vdsInCluster : vdsList) {
if (vdsWithRunningVMs.contains(vdsInCluster.getId())) {
candidateHostsWithRunningVms.add(vdsInCluster.getName());
}
}
// cluster
if (!candidateHostsWithRunningVms.isEmpty()) {
addClusterDetails(clusterID, problematicClusters);
allHostsWithRunningVms.addAll(candidateHostsWithRunningVms);
}
}
}
// If there are problematic clusters
result = problematicClusters.isEmpty();
if (!result) {
addValidationMessage(EngineMessage.CANNOT_MAINTENANCE_VDS_RUN_VMS_NO_OTHER_RUNNING_VDS);
String commaDelimitedClusters = StringUtils.join(problematicClusters, ",");
getReturnValue().getValidationMessages().add(String.format("$ClustersList %1$s", commaDelimitedClusters));
getReturnValue().getValidationMessages().add(String.format("$HostsList %1$s", StringUtils.join(allHostsWithRunningVms, ",")));
}
}
if (result && !getParameters().isForceMaintenance()) {
result = validateGlusterParams(clustersAsSet);
}
}
return result;
}
use of org.ovirt.engine.core.bll.validator.MultipleVmsValidator in project ovirt-engine by oVirt.
the class MigrateVmCommand method validateImpl.
@Override
protected boolean validateImpl() {
final VM vm = getVm();
if (vm == null) {
return failValidation(EngineMessage.ACTION_TYPE_FAILED_VM_NOT_FOUND);
}
if (!canRunActionOnNonManagedVm()) {
return false;
}
VmValidator vmValidator = getVmValidator();
if (!validate(vmValidator.isVmPluggedDiskNotUsingScsiReservation())) {
return false;
}
if (!FeatureSupported.isMigrationSupported(getCluster().getArchitecture(), getCluster().getCompatibilityVersion())) {
return failValidation(EngineMessage.MIGRATION_IS_NOT_SUPPORTED);
}
// If VM is pinned to host, no migration can occur
if (vm.getMigrationSupport() == MigrationSupport.PINNED_TO_HOST) {
return failValidation(EngineMessage.ACTION_TYPE_FAILED_VM_IS_PINNED_TO_HOST);
}
if (vm.getMigrationSupport() == MigrationSupport.IMPLICITLY_NON_MIGRATABLE && !getParameters().isForceMigrationForNonMigratableVm()) {
return failValidation(EngineMessage.ACTION_TYPE_FAILED_VM_IS_NON_MIGRTABLE_AND_IS_NOT_FORCED_BY_USER_TO_MIGRATE);
}
switch(vm.getStatus()) {
case MigratingFrom:
return failValidation(EngineMessage.ACTION_TYPE_FAILED_MIGRATION_IN_PROGRESS);
case NotResponding:
return failVmStatusIllegal();
case Paused:
if (vm.getVmPauseStatus() == VmPauseStatus.EIO) {
return failValidation(EngineMessage.MIGRATE_PAUSED_EIO_VM_IS_NOT_SUPPORTED);
}
break;
default:
}
if (!vm.isQualifyToMigrate()) {
return failValidation(EngineMessage.ACTION_TYPE_FAILED_VM_IS_NOT_RUNNING);
}
if (!validate(new MultipleVmsValidator(vm).vmNotHavingPluggedDiskSnapshots(EngineMessage.ACTION_TYPE_FAILED_VM_HAS_PLUGGED_DISK_SNAPSHOT)) || !validate(vmValidator.allPassthroughVnicsMigratable())) {
return false;
}
if (getParameters().getTargetClusterId() != null) {
ChangeVmClusterValidator changeVmClusterValidator = ChangeVmClusterValidator.create(this, getParameters().getTargetClusterId(), getVm().getCustomCompatibilityVersion());
if (!changeVmClusterValidator.validate()) {
return false;
}
}
if (isInternalExecution() && getVm().getMigrationSupport() != MigrationSupport.MIGRATABLE) {
return failValidation(EngineMessage.ACTION_TYPE_FAILED_VM_IS_NON_MIGRTABLE);
}
return validate(snapshotsValidator.vmNotDuringSnapshot(vm.getId())) && // TODO: replace it with a better solution
validate(new DiskImagesValidator(callFilterImageDisks(vm)).diskImagesNotLocked()) && !schedulingManager.canSchedule(getCluster(), getVm(), getVdsBlackList(), getVdsWhiteList(), getReturnValue().getValidationMessages()).isEmpty();
}
Aggregations