mirror of https://github.com/apache/cloudstack.git
CLOUDSTACK-3382. Alert should be raised if a vm is migrated from dedicated to non-dedicated resource and vice versa.
Alerts are generated for VM migration between: 1) Source host is dedicated and destination host is not. 2) Source host is not dedicated and destination host is dedicated. 3) Both hosts are dedicated to different accounts/domains
This commit is contained in:
parent
c319ba3ba7
commit
e2f2bc5f0b
|
|
@ -27,4 +27,6 @@ public interface PlannerHostReservationDao extends GenericDao<PlannerHostReserva
|
|||
|
||||
List<PlannerHostReservationVO> listAllReservedHosts();
|
||||
|
||||
List<PlannerHostReservationVO> listAllDedicatedHosts();
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ import java.util.List;
|
|||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.ejb.Local;
|
||||
|
||||
import com.cloud.deploy.DeploymentPlanner.PlannerResourceUsage;
|
||||
import com.cloud.deploy.PlannerHostReservationVO;
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
|
|
@ -31,6 +33,7 @@ public class PlannerHostReservationDaoImpl extends GenericDaoBase<PlannerHostRes
|
|||
|
||||
private SearchBuilder<PlannerHostReservationVO> _hostIdSearch;
|
||||
private SearchBuilder<PlannerHostReservationVO> _reservedHostSearch;
|
||||
private SearchBuilder<PlannerHostReservationVO> _dedicatedHostSearch;;
|
||||
|
||||
public PlannerHostReservationDaoImpl() {
|
||||
|
||||
|
|
@ -45,6 +48,10 @@ public class PlannerHostReservationDaoImpl extends GenericDaoBase<PlannerHostRes
|
|||
_reservedHostSearch = createSearchBuilder();
|
||||
_reservedHostSearch.and("usage", _reservedHostSearch.entity().getResourceUsage(), SearchCriteria.Op.NNULL);
|
||||
_reservedHostSearch.done();
|
||||
|
||||
_dedicatedHostSearch = createSearchBuilder();
|
||||
_dedicatedHostSearch.and("usage", _dedicatedHostSearch.entity().getResourceUsage(), SearchCriteria.Op.EQ);
|
||||
_dedicatedHostSearch.done();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -60,4 +67,10 @@ public class PlannerHostReservationDaoImpl extends GenericDaoBase<PlannerHostRes
|
|||
return listBy(sc);
|
||||
}
|
||||
|
||||
}
|
||||
@Override
|
||||
public List<PlannerHostReservationVO> listAllDedicatedHosts() {
|
||||
SearchCriteria<PlannerHostReservationVO> sc = _dedicatedHostSearch.create();
|
||||
sc.setParameters("usage", PlannerResourceUsage.Dedicated);
|
||||
return listBy(sc);
|
||||
}
|
||||
}
|
||||
|
|
@ -33,10 +33,6 @@ import javax.ejb.Local;
|
|||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.server.ConfigurationServer;
|
||||
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
|
||||
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
|
||||
import org.apache.cloudstack.affinity.AffinityGroupService;
|
||||
|
|
@ -68,6 +64,8 @@ import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
|
|||
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||
import org.apache.cloudstack.storage.to.TemplateObjectTO;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.agent.AgentManager;
|
||||
import com.cloud.agent.AgentManager.OnError;
|
||||
|
|
@ -111,6 +109,8 @@ import com.cloud.dc.dao.HostPodDao;
|
|||
import com.cloud.deploy.DataCenterDeployment;
|
||||
import com.cloud.deploy.DeployDestination;
|
||||
import com.cloud.deploy.DeploymentPlanner.ExcludeList;
|
||||
import com.cloud.deploy.PlannerHostReservationVO;
|
||||
import com.cloud.deploy.dao.PlannerHostReservationDao;
|
||||
import com.cloud.domain.DomainVO;
|
||||
import com.cloud.domain.dao.DomainDao;
|
||||
import com.cloud.event.ActionEvent;
|
||||
|
|
@ -178,9 +178,11 @@ import com.cloud.projects.Project.ListProjectResourcesCriteria;
|
|||
import com.cloud.projects.ProjectManager;
|
||||
import com.cloud.resource.ResourceManager;
|
||||
import com.cloud.resource.ResourceState;
|
||||
import com.cloud.server.ConfigurationServer;
|
||||
import com.cloud.server.Criteria;
|
||||
import com.cloud.service.ServiceOfferingVO;
|
||||
import com.cloud.service.dao.ServiceOfferingDao;
|
||||
import com.cloud.service.dao.ServiceOfferingDetailsDao;
|
||||
import com.cloud.storage.DiskOfferingVO;
|
||||
import com.cloud.storage.GuestOSCategoryVO;
|
||||
import com.cloud.storage.GuestOSVO;
|
||||
|
|
@ -225,6 +227,7 @@ import com.cloud.user.dao.SSHKeyPairDao;
|
|||
import com.cloud.user.dao.UserDao;
|
||||
import com.cloud.user.dao.VmDiskStatisticsDao;
|
||||
import com.cloud.uservm.UserVm;
|
||||
import com.cloud.utils.DateUtil;
|
||||
import com.cloud.utils.Journal;
|
||||
import com.cloud.utils.NumbersUtil;
|
||||
import com.cloud.utils.Pair;
|
||||
|
|
@ -422,11 +425,16 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
|||
ConfigurationServer _configServer;
|
||||
@Inject
|
||||
AffinityGroupService _affinityGroupService;
|
||||
@Inject
|
||||
PlannerHostReservationDao _plannerHostReservationDao;
|
||||
@Inject
|
||||
private ServiceOfferingDetailsDao serviceOfferingDetailsDao;
|
||||
|
||||
protected ScheduledExecutorService _executor = null;
|
||||
protected int _expungeInterval;
|
||||
protected int _expungeDelay;
|
||||
protected boolean _dailyOrHourly = false;
|
||||
private int capacityReleaseInterval;
|
||||
|
||||
protected String _name;
|
||||
protected String _instance;
|
||||
|
|
@ -1428,6 +1436,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
|||
|
||||
String workers = configs.get("expunge.workers");
|
||||
int wrks = NumbersUtil.parseInt(workers, 10);
|
||||
capacityReleaseInterval = NumbersUtil.parseInt(_configDao.getValue(Config.CapacitySkipcountingHours.key()), 3600);
|
||||
|
||||
String time = configs.get("expunge.interval");
|
||||
_expungeInterval = NumbersUtil.parseInt(time, 86400);
|
||||
|
|
@ -3868,22 +3877,9 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
|||
+ destinationHost.getResourceState());
|
||||
}
|
||||
|
||||
HostVO srcHost = _hostDao.findById(srcHostId);
|
||||
HostVO destHost = _hostDao.findById(destinationHost.getId());
|
||||
//if srcHost is dedicated and destination Host is not
|
||||
if (checkIfHostIsDedicated(srcHost) && !checkIfHostIsDedicated(destHost)) {
|
||||
//raise an alert
|
||||
String msg = "VM is migrated on a non-dedicated host " + destinationHost.getName();
|
||||
_alertMgr.sendAlert(AlertManager.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg);
|
||||
}
|
||||
//if srcHost is non dedicated but destination Host is.
|
||||
if (!checkIfHostIsDedicated(srcHost) && checkIfHostIsDedicated(destHost)) {
|
||||
//raise an alert
|
||||
String msg = "VM is migrated on a dedicated host " + destinationHost.getName();
|
||||
_alertMgr.sendAlert(AlertManager.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg);
|
||||
}
|
||||
checkHostsDedication(vm, srcHostId, destinationHost.getId());
|
||||
|
||||
// call to core process
|
||||
// call to core process
|
||||
DataCenterVO dcVO = _dcDao.findById(destinationHost.getDataCenterId());
|
||||
HostPodVO pod = _podDao.findById(destinationHost.getPodId());
|
||||
Cluster cluster = _clusterDao.findById(destinationHost.getClusterId());
|
||||
|
|
@ -3926,6 +3922,210 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
|||
}
|
||||
}
|
||||
|
||||
private Long accountOfDedicatedHost(HostVO host) {
|
||||
long hostId = host.getId();
|
||||
DedicatedResourceVO dedicatedHost = _dedicatedDao.findByHostId(hostId);
|
||||
DedicatedResourceVO dedicatedClusterOfHost = _dedicatedDao.findByClusterId(host.getClusterId());
|
||||
DedicatedResourceVO dedicatedPodOfHost = _dedicatedDao.findByPodId(host.getPodId());
|
||||
if(dedicatedHost != null) {
|
||||
return dedicatedHost.getAccountId();
|
||||
}
|
||||
if(dedicatedClusterOfHost != null) {
|
||||
return dedicatedClusterOfHost.getAccountId();
|
||||
}
|
||||
if(dedicatedPodOfHost != null) {
|
||||
return dedicatedPodOfHost.getAccountId();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Long domainOfDedicatedHost(HostVO host) {
|
||||
long hostId = host.getId();
|
||||
DedicatedResourceVO dedicatedHost = _dedicatedDao.findByHostId(hostId);
|
||||
DedicatedResourceVO dedicatedClusterOfHost = _dedicatedDao.findByClusterId(host.getClusterId());
|
||||
DedicatedResourceVO dedicatedPodOfHost = _dedicatedDao.findByPodId(host.getPodId());
|
||||
if(dedicatedHost != null) {
|
||||
return dedicatedHost.getDomainId();
|
||||
}
|
||||
if(dedicatedClusterOfHost != null) {
|
||||
return dedicatedClusterOfHost.getDomainId();
|
||||
}
|
||||
if(dedicatedPodOfHost != null) {
|
||||
return dedicatedPodOfHost.getDomainId();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void checkHostsDedication (VMInstanceVO vm, long srcHostId, long destHostId) {
|
||||
HostVO srcHost = _hostDao.findById(srcHostId);
|
||||
HostVO destHost = _hostDao.findById(destHostId);
|
||||
boolean srcExplDedicated = checkIfHostIsDedicated(srcHost);
|
||||
boolean destExplDedicated = checkIfHostIsDedicated(destHost);
|
||||
//if srcHost is explicitly dedicated and destination Host is not
|
||||
if (srcExplDedicated && !destExplDedicated) {
|
||||
//raise an alert
|
||||
String msg = "VM is being migrated from a explicitly dedicated host " + srcHost.getName() +" to non-dedicated host " + destHost.getName();
|
||||
_alertMgr.sendAlert(AlertManager.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg);
|
||||
s_logger.warn(msg);
|
||||
}
|
||||
//if srcHost is non dedicated but destination Host is explicitly dedicated
|
||||
if (!srcExplDedicated && destExplDedicated) {
|
||||
//raise an alert
|
||||
String msg = "VM is being migrated from a non dedicated host " + srcHost.getName() + " to a explicitly dedicated host "+ destHost.getName();
|
||||
_alertMgr.sendAlert(AlertManager.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg);
|
||||
s_logger.warn(msg);
|
||||
}
|
||||
|
||||
//if hosts are dedicated to different account/domains, raise an alert
|
||||
if (srcExplDedicated && destExplDedicated) {
|
||||
if((accountOfDedicatedHost(srcHost) != null) && (accountOfDedicatedHost(srcHost)!= accountOfDedicatedHost(destHost))) {
|
||||
String msg = "VM is being migrated from host " + srcHost.getName() + " explicitly dedicated to account " + accountOfDedicatedHost(srcHost) +
|
||||
" to host " + destHost.getName() + " explicitly dedicated to account " + accountOfDedicatedHost(destHost);
|
||||
_alertMgr.sendAlert(AlertManager.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg);
|
||||
s_logger.warn(msg);
|
||||
}
|
||||
if((domainOfDedicatedHost(srcHost) != null) && (domainOfDedicatedHost(srcHost)!= domainOfDedicatedHost(destHost))) {
|
||||
String msg = "VM is being migrated from host " + srcHost.getName() + " explicitly dedicated to domain " + domainOfDedicatedHost(srcHost) +
|
||||
" to host " + destHost.getName() + " explicitly dedicated to domain " + domainOfDedicatedHost(destHost);
|
||||
_alertMgr.sendAlert(AlertManager.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg);
|
||||
s_logger.warn(msg);
|
||||
}
|
||||
}
|
||||
|
||||
// Checks for implicitly dedicated hosts
|
||||
ServiceOfferingVO deployPlanner = _offeringDao.findById(vm.getServiceOfferingId());
|
||||
if(deployPlanner.getDeploymentPlanner() != null && deployPlanner.getDeploymentPlanner().equals("ImplicitDedicationPlanner")) {
|
||||
//VM is deployed using implicit planner
|
||||
long accountOfVm = vm.getAccountId();
|
||||
String msg = "VM of account " + accountOfVm + " with implicit deployment planner being migrated to host " + destHost.getName();
|
||||
//Get all vms on destination host
|
||||
boolean emptyDestination = false;
|
||||
List<VMInstanceVO> vmsOnDest= getVmsOnHost(destHostId);
|
||||
if (vmsOnDest == null || vmsOnDest.isEmpty()) {
|
||||
emptyDestination = true;
|
||||
}
|
||||
|
||||
if (!emptyDestination) {
|
||||
//Check if vm is deployed using strict implicit planner
|
||||
if(!isServiceOfferingUsingPlannerInPreferredMode(vm.getServiceOfferingId())) {
|
||||
//Check if all vms on destination host are created using strict implicit mode
|
||||
if(!checkIfAllVmsCreatedInStrictMode(accountOfVm, vmsOnDest)) {
|
||||
msg = "VM of account " + accountOfVm + " with strict implicit deployment planner being migrated to host " + destHost.getName() +
|
||||
" not having all vms strict implicitly dedicated to account " + accountOfVm;
|
||||
}
|
||||
} else {
|
||||
//If vm is deployed using preferred implicit planner, check if all vms on destination host must be
|
||||
//using implicit planner and must belong to same account
|
||||
for (VMInstanceVO vmsDest : vmsOnDest) {
|
||||
ServiceOfferingVO destPlanner = _offeringDao.findById(vmsDest.getServiceOfferingId());
|
||||
if (!((destPlanner.getDeploymentPlanner() != null && destPlanner.getDeploymentPlanner().equals("ImplicitDedicationPlanner")) &&
|
||||
vmsDest.getAccountId()==accountOfVm)) {
|
||||
msg = "VM of account " + accountOfVm + " with preffered implicit deployment planner being migrated to host " + destHost.getName() +
|
||||
" not having all vms implicitly dedicated to account " + accountOfVm;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_alertMgr.sendAlert(AlertManager.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg);
|
||||
s_logger.warn(msg);
|
||||
|
||||
} else {
|
||||
//VM is not deployed using implicit planner, check if it migrated between dedicated hosts
|
||||
List<PlannerHostReservationVO> reservedHosts = _plannerHostReservationDao.listAllDedicatedHosts();
|
||||
boolean srcImplDedicated = false;
|
||||
boolean destImplDedicated = false;
|
||||
String msg = null;
|
||||
for (PlannerHostReservationVO reservedHost : reservedHosts) {
|
||||
if(reservedHost.getHostId() == srcHostId) {
|
||||
srcImplDedicated = true;
|
||||
}
|
||||
if(reservedHost.getHostId() == destHostId) {
|
||||
destImplDedicated = true;
|
||||
}
|
||||
}
|
||||
if(srcImplDedicated) {
|
||||
if(destImplDedicated){
|
||||
msg = "VM is being migrated from implicitly dedicated host " + srcHost.getName() + " to another implicitly dedicated host " + destHost.getName();
|
||||
} else {
|
||||
msg = "VM is being migrated from implicitly dedicated host " + srcHost.getName() + " to shared host " + destHost.getName();
|
||||
}
|
||||
_alertMgr.sendAlert(AlertManager.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg);
|
||||
s_logger.warn(msg);
|
||||
} else {
|
||||
if (destImplDedicated) {
|
||||
msg = "VM is being migrated from shared host " + srcHost.getName() + " to implicitly dedicated host " + destHost.getName();
|
||||
_alertMgr.sendAlert(AlertManager.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg);
|
||||
s_logger.warn(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<VMInstanceVO> getVmsOnHost(long hostId) {
|
||||
List<VMInstanceVO> vms = _vmInstanceDao.listUpByHostId(hostId);
|
||||
List<VMInstanceVO> vmsByLastHostId = _vmInstanceDao.listByLastHostId(hostId);
|
||||
if (vmsByLastHostId.size() > 0) {
|
||||
// check if any VMs are within skip.counting.hours, if yes we have to consider the host.
|
||||
for (VMInstanceVO stoppedVM : vmsByLastHostId) {
|
||||
long secondsSinceLastUpdate = (DateUtil.currentGMTTime().getTime() - stoppedVM.getUpdateTime()
|
||||
.getTime()) / 1000;
|
||||
if (secondsSinceLastUpdate < capacityReleaseInterval) {
|
||||
vms.add(stoppedVM);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return vms;
|
||||
}
|
||||
private boolean isServiceOfferingUsingPlannerInPreferredMode(long serviceOfferingId) {
|
||||
boolean preferred = false;
|
||||
Map<String, String> details = serviceOfferingDetailsDao.findDetails(serviceOfferingId);
|
||||
if (details != null && !details.isEmpty()) {
|
||||
String preferredAttribute = details.get("ImplicitDedicationMode");
|
||||
if (preferredAttribute != null && preferredAttribute.equals("Preferred")) {
|
||||
preferred = true;
|
||||
}
|
||||
}
|
||||
return preferred;
|
||||
}
|
||||
|
||||
private boolean checkIfAllVmsCreatedInStrictMode(Long accountId, List<VMInstanceVO> allVmsOnHost) {
|
||||
boolean createdByImplicitStrict = true;
|
||||
if (allVmsOnHost.isEmpty())
|
||||
return false;
|
||||
for (VMInstanceVO vm : allVmsOnHost) {
|
||||
if (!isImplicitPlannerUsedByOffering(vm.getServiceOfferingId()) || vm.getAccountId()!= accountId) {
|
||||
s_logger.info("Host " + vm.getHostId() + " found to be running a vm created by a planner other" +
|
||||
" than implicit, or running vms of other account");
|
||||
createdByImplicitStrict = false;
|
||||
break;
|
||||
} else if (isServiceOfferingUsingPlannerInPreferredMode(vm.getServiceOfferingId()) || vm.getAccountId()!= accountId) {
|
||||
s_logger.info("Host " + vm.getHostId() + " found to be running a vm created by an implicit planner" +
|
||||
" in preferred mode, or running vms of other account");
|
||||
createdByImplicitStrict = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return createdByImplicitStrict;
|
||||
}
|
||||
|
||||
private boolean isImplicitPlannerUsedByOffering(long offeringId) {
|
||||
boolean implicitPlannerUsed = false;
|
||||
ServiceOfferingVO offering = _serviceOfferingDao.findByIdIncludingRemoved(offeringId);
|
||||
if (offering == null) {
|
||||
s_logger.error("Couldn't retrieve the offering by the given id : " + offeringId);
|
||||
} else {
|
||||
String plannerName = offering.getDeploymentPlanner();
|
||||
if (plannerName != null) {
|
||||
if(plannerName.equals("ImplicitDedicationPlanner")) {
|
||||
implicitPlannerUsed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return implicitPlannerUsed;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_VM_MIGRATE, eventDescription = "migrating VM", async = true)
|
||||
public VirtualMachine migrateVirtualMachineWithVolume(Long vmId, Host destinationHost,
|
||||
|
|
@ -4043,6 +4243,8 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
|||
" migrate to this host");
|
||||
}
|
||||
|
||||
checkHostsDedication(vm, srcHostId, destinationHost.getId());
|
||||
|
||||
VMInstanceVO migratedVm = _itMgr.migrateWithStorage(vm, srcHostId, destinationHost.getId(), volToPoolObjectMap);
|
||||
return migratedVm;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue