Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;

Expand All @@ -35,13 +36,15 @@
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.cloudstack.network.router.deployment.RouterDeploymentDefinition;
import org.apache.cloudstack.utils.CloudStackVersion;
import org.apache.commons.collections.CollectionUtils;
import org.apache.log4j.Logger;

import com.cloud.agent.AgentManager;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.to.NicTO;
import com.cloud.agent.manager.Commands;
import com.cloud.alert.AlertManager;
import com.cloud.capacity.CapacityManager;
import com.cloud.configuration.Config;
import com.cloud.dc.ClusterVO;
import com.cloud.dc.DataCenter;
Expand Down Expand Up @@ -167,6 +170,8 @@ public class NetworkHelperImpl implements NetworkHelper {
RouterHealthCheckResultDao _routerHealthCheckResultDao;
@Inject
Ipv6Service ipv6Service;
@Inject
CapacityManager capacityMgr;

protected final Map<HypervisorType, ConfigKey<String>> hypervisorsMap = new HashMap<>();

Expand Down Expand Up @@ -502,12 +507,12 @@ public DomainRouterVO deployRouter(final RouterDeploymentDefinition routerDeploy
// failed both times, throw the exception up
final List<HypervisorType> hypervisors = getHypervisors(routerDeploymentDefinition);

int allocateRetry = 0;
int startRetry = 0;
DomainRouterVO router = null;
for (final Iterator<HypervisorType> iter = hypervisors.iterator(); iter.hasNext();) {
final HypervisorType hType = iter.next();
try {
checkIfZoneHasCapacity(routerDeploymentDefinition.getDest().getDataCenter(), hType, routerOffering);

final long id = _routerDao.getNextInSequence(Long.class, "id");
if (s_logger.isDebugEnabled()) {
s_logger.debug(String.format("Allocating the VR with id=%s in datacenter %s with the hypervisor type %s", id, routerDeploymentDefinition.getDest()
Expand Down Expand Up @@ -547,31 +552,27 @@ public DomainRouterVO deployRouter(final RouterDeploymentDefinition routerDeploy
reallocateRouterNetworks(routerDeploymentDefinition, router, template, null);
router = _routerDao.findById(router.getId());
} catch (final InsufficientCapacityException ex) {
if (allocateRetry < 2 && iter.hasNext()) {
if (iter.hasNext()) {
Comment thread
weizhouapache marked this conversation as resolved.
s_logger.debug("Failed to allocate the VR with hypervisor type " + hType + ", retrying one more time");
continue;
} else {
throw ex;
}
} finally {
allocateRetry++;
}

if (startRouter) {
try {
router = startVirtualRouter(router, _accountMgr.getSystemUser(), _accountMgr.getSystemAccount(), routerDeploymentDefinition.getParams());
break;
} catch (final InsufficientCapacityException ex) {
if (startRetry < 2 && iter.hasNext()) {
if (iter.hasNext()) {
s_logger.debug("Failed to start the VR " + router + " with hypervisor type " + hType + ", " + "destroying it and recreating one more time");
// destroy the router
destroyRouter(router.getId(), _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM), User.UID_SYSTEM);
continue;
} else {
throw ex;
}
} finally {
startRetry++;
}
} else {
// return stopped router
Expand All @@ -582,6 +583,25 @@ public DomainRouterVO deployRouter(final RouterDeploymentDefinition routerDeploy
return router;
}

private void checkIfZoneHasCapacity(final DataCenter zone, final HypervisorType hypervisorType, final ServiceOfferingVO routerOffering) throws InsufficientServerCapacityException {
List <HostVO> hosts = _hostDao.listByDataCenterIdAndHypervisorType(zone.getId(), hypervisorType);
if (CollectionUtils.isEmpty(hosts)) {
String msg = String.format("Zone %s has no %s host available which is enabled and in Up state", zone.getName(), hypervisorType);
s_logger.debug(msg);
throw new InsufficientServerCapacityException(msg, DataCenter.class, zone.getId());
}
for (HostVO host : hosts) {
Pair<Boolean, Boolean> cpuCapabilityAndCapacity = capacityMgr.checkIfHostHasCpuCapabilityAndCapacity(host, routerOffering, false);
if (cpuCapabilityAndCapacity.first() && cpuCapabilityAndCapacity.second()) {
s_logger.debug("Host " + host + " has enough capacity for the router");
return;
}
}
String msg = String.format("Zone %s has no %s host which has enough capacity", zone.getName(), hypervisorType);
s_logger.debug(msg);
throw new InsufficientServerCapacityException(msg, DataCenter.class, zone.getId());
}

protected void filterSupportedHypervisors(final List<HypervisorType> hypervisors) {
// For non vpc we keep them all assuming all types in the list are
// supported
Expand Down Expand Up @@ -618,7 +638,7 @@ protected List<HypervisorType> getHypervisors(final RouterDeploymentDefinition r
throw new InsufficientServerCapacityException("Unable to create virtual router, there are no clusters in the zone." + getNoHypervisorsErrMsgDetails(),
DataCenter.class, dest.getDataCenter().getId());
}
return hypervisors;
return new ArrayList(new LinkedHashSet<>(hypervisors));
Comment thread
weizhouapache marked this conversation as resolved.
}

/*
Expand Down