mirror of https://github.com/apache/cloudstack.git
Bug 11169 - Couldn't deploy a router because the host it existed on is in Maintenance.
Changes: - VirtualMachineMgr puts the constraint that if Root volume is already READY, we provide the clusterId in the plan to the deploymentPlanner. Planner then searches for resources only under that cluster. - If no deployment could be found, deploying VM fails. - Fixed this, such that incase the root volume is recreatable, we call the planner again by removing the cluster constraint. Planner will then search for resources in other clusters. - Works for system VMs(SSVM, consoleproxy, virual routers).
This commit is contained in:
parent
96afeaf38f
commit
25196871b9
|
|
@ -611,6 +611,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene
|
|||
}
|
||||
plan = (DataCenterDeployment)planToDeploy;
|
||||
}
|
||||
|
||||
HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vm.getHypervisorType());
|
||||
|
||||
boolean canRetry = true;
|
||||
|
|
@ -629,51 +630,59 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene
|
|||
+ ", clusters: " + avoids.getClustersToAvoid()
|
||||
+ ", hosts: " + avoids.getHostsToAvoid());
|
||||
}
|
||||
int retry = _retry;
|
||||
while (retry-- != 0) { // It's != so that it can match -1.
|
||||
// edit plan if this vm's ROOT volume is in READY state already
|
||||
// edit plan if this vm's ROOT volume is in READY state already
|
||||
List<VolumeVO> vols = _volsDao.findReadyRootVolumesByInstance(vm.getId());
|
||||
|
||||
for (VolumeVO vol : vols) {
|
||||
// make sure if the templateId is unchanged. If it is changed, let planner
|
||||
// reassign pool for the volume even if it ready.
|
||||
Long volTemplateId = vol.getTemplateId();
|
||||
if (volTemplateId != null && volTemplateId.longValue() != template.getId()) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug(vol + " of " + vm + " is READY, but template ids don't match, let the planner reassign a new pool");
|
||||
}
|
||||
continue;
|
||||
|
||||
// edit plan if this vm's ROOT volume is in READY state already
|
||||
List<VolumeVO> vols = _volsDao.findReadyRootVolumesByInstance(vm.getId());
|
||||
boolean planChangedByVolume = false;
|
||||
boolean rootVolumeisRecreatable = false;
|
||||
DataCenterDeployment originalPlan = plan;
|
||||
for (VolumeVO vol : vols) {
|
||||
// make sure if the templateId is unchanged. If it is changed, let planner
|
||||
// reassign pool for the volume even if it ready.
|
||||
Long volTemplateId = vol.getTemplateId();
|
||||
if (volTemplateId != null && volTemplateId.longValue() != template.getId()) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug(vol + " of " + vm + " is READY, but template ids don't match, let the planner reassign a new pool");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
StoragePoolVO pool = _storagePoolDao.findById(vol.getPoolId());
|
||||
if (!pool.isInMaintenance()) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Root volume is ready, need to place VM in volume's cluster");
|
||||
}
|
||||
long rootVolDcId = pool.getDataCenterId();
|
||||
Long rootVolPodId = pool.getPodId();
|
||||
Long rootVolClusterId = pool.getClusterId();
|
||||
if(planToDeploy != null && planToDeploy.getDataCenterId() != 0){
|
||||
Long clusterIdSpecified = planToDeploy.getClusterId();
|
||||
if(clusterIdSpecified != null && rootVolClusterId != null){
|
||||
if(rootVolClusterId.longValue() != clusterIdSpecified.longValue()){
|
||||
//cannot satisfy the plan passed in to the planner
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Cannot satisfy the deployment plan passed in since the ready Root volume is in different cluster. volume's cluster: "+rootVolClusterId + ", cluster specified: "+clusterIdSpecified);
|
||||
}
|
||||
throw new ResourceUnavailableException("Root volume is ready in different cluster, Deployment plan provided cannot be satisfied, unable to create a deployment for " + vm, Cluster.class, clusterIdSpecified);
|
||||
StoragePoolVO pool = _storagePoolDao.findById(vol.getPoolId());
|
||||
if (!pool.isInMaintenance()) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Root volume is ready, need to place VM in volume's cluster");
|
||||
}
|
||||
long rootVolDcId = pool.getDataCenterId();
|
||||
Long rootVolPodId = pool.getPodId();
|
||||
Long rootVolClusterId = pool.getClusterId();
|
||||
if(planToDeploy != null && planToDeploy.getDataCenterId() != 0){
|
||||
Long clusterIdSpecified = planToDeploy.getClusterId();
|
||||
if(clusterIdSpecified != null && rootVolClusterId != null){
|
||||
if(rootVolClusterId.longValue() != clusterIdSpecified.longValue()){
|
||||
//cannot satisfy the plan passed in to the planner
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Cannot satisfy the deployment plan passed in since the ready Root volume is in different cluster. volume's cluster: "+rootVolClusterId + ", cluster specified: "+clusterIdSpecified);
|
||||
}
|
||||
}
|
||||
plan = new DataCenterDeployment(planToDeploy.getDataCenterId(), planToDeploy.getPodId(), planToDeploy.getClusterId(), planToDeploy.getHostId(), vol.getPoolId());
|
||||
}else{
|
||||
plan = new DataCenterDeployment(rootVolDcId, rootVolPodId, rootVolClusterId, null, vol.getPoolId());
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug(vol + " is READY, changing deployment plan to use this pool's dcId: " + rootVolDcId + " , podId: " + rootVolPodId + " , and clusterId: " + rootVolClusterId);
|
||||
throw new ResourceUnavailableException("Root volume is ready in different cluster, Deployment plan provided cannot be satisfied, unable to create a deployment for " + vm, Cluster.class, clusterIdSpecified);
|
||||
}
|
||||
}
|
||||
plan = new DataCenterDeployment(planToDeploy.getDataCenterId(), planToDeploy.getPodId(), planToDeploy.getClusterId(), planToDeploy.getHostId(), vol.getPoolId());
|
||||
}else{
|
||||
plan = new DataCenterDeployment(rootVolDcId, rootVolPodId, rootVolClusterId, null, vol.getPoolId());
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug(vol + " is READY, changing deployment plan to use this pool's dcId: " + rootVolDcId + " , podId: " + rootVolPodId + " , and clusterId: " + rootVolClusterId);
|
||||
}
|
||||
planChangedByVolume = true;
|
||||
if(vol.isRecreatable()){
|
||||
rootVolumeisRecreatable = true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int retry = _retry;
|
||||
while (retry-- != 0) { // It's != so that it can match -1.
|
||||
|
||||
VirtualMachineProfileImpl<T> vmProfile = new VirtualMachineProfileImpl<T>(vm, template, offering, account, params);
|
||||
DeployDestination dest = null;
|
||||
|
|
@ -691,6 +700,13 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene
|
|||
}
|
||||
|
||||
if (dest == null) {
|
||||
if(planChangedByVolume){
|
||||
if(rootVolumeisRecreatable){
|
||||
plan = originalPlan;
|
||||
planChangedByVolume = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
throw new InsufficientServerCapacityException("Unable to create a deployment for " + vmProfile, DataCenter.class, plan.getDataCenterId());
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue