CLOUDSTACK-70: Improve restart network behaviour for basic network

If cleanup=true, network elements and resources are shutdown and
reimplemented. Else, shutdown/reimplementation is skipped. Enabled
cleanup checkbox in CS UI.

For both cases, VRs are only deployed for Pods with no running
or starting VRs and Pods having running or starting user vms.

New DAO helpers introduced:
HostPodDao: listByDataCenterIdVMTypeAndStates
DomainRouterDao: listByPodId and listByPodIdAndStates
VMInstanceDao: listByPodId and corrected definition of listByTypeAndState

Signed-off-by: Rohit Yadav <bhaisaab@apache.org>
This commit is contained in:
Rohit Yadav 2012-10-11 18:30:00 +05:30
parent eac941d590
commit 6dd5c3fd42
9 changed files with 185 additions and 88 deletions

View File

@ -21,11 +21,14 @@ import java.util.List;
import com.cloud.dc.HostPodVO;
import com.cloud.utils.db.GenericDao;
import com.cloud.vm.VirtualMachine;
public interface HostPodDao extends GenericDao<HostPodVO, Long> {
public List<HostPodVO> listByDataCenterId(long id);
public HostPodVO findByName(String name, long dcId);
public List<HostPodVO> listByDataCenterIdVMTypeAndStates(long id, VirtualMachine.Type type, VirtualMachine.State... states);
public HostPodVO findByName(String name, long dcId);
public HashMap<Long, List<Object>> getCurrentPodCidrSubnets(long zoneId, long podIdToSkip);

View File

@ -31,10 +31,15 @@ import com.cloud.dc.HostPodVO;
import com.cloud.org.Grouping;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.GenericSearchBuilder;
import com.cloud.utils.db.JoinBuilder;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.SearchCriteria.Op;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.component.ComponentLocator;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.dao.VMInstanceDaoImpl;
@Local(value={HostPodDao.class})
public class HostPodDaoImpl extends GenericDaoBase<HostPodVO, Long> implements HostPodDao {
@ -61,7 +66,28 @@ public class HostPodDaoImpl extends GenericDaoBase<HostPodVO, Long> implements H
return listBy(sc);
}
@Override
public List<HostPodVO> listByDataCenterIdVMTypeAndStates(long id, VirtualMachine.Type type, VirtualMachine.State... states) {
final VMInstanceDaoImpl _vmDao = ComponentLocator.inject(VMInstanceDaoImpl.class);
SearchBuilder<VMInstanceVO> vmInstanceSearch = _vmDao.createSearchBuilder();
vmInstanceSearch.and("type", vmInstanceSearch.entity().getType(), SearchCriteria.Op.EQ);
vmInstanceSearch.and("states", vmInstanceSearch.entity().getState(), SearchCriteria.Op.IN);
SearchBuilder<HostPodVO> podIdSearch = createSearchBuilder();
podIdSearch.and("dc", podIdSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
podIdSearch.select(null, SearchCriteria.Func.DISTINCT, podIdSearch.entity().getId());
podIdSearch.join("vmInstanceSearch", vmInstanceSearch, podIdSearch.entity().getId(),
vmInstanceSearch.entity().getPodIdToDeployIn(), JoinBuilder.JoinType.INNER);
podIdSearch.done();
SearchCriteria<HostPodVO> sc = podIdSearch.create();
sc.setParameters("dc", id);
sc.setJoinParameters("vmInstanceSearch", "type", type);
sc.setJoinParameters("vmInstanceSearch", "states", (Object[]) states);
return listBy(sc);
}
@Override
public HostPodVO findByName(String name, long dcId) {
SearchCriteria<HostPodVO> sc = DataCenterAndNameSearch.create();

View File

@ -3807,12 +3807,6 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
throw new InvalidParameterValueException("Network is not in the right state to be restarted. Correct states are: " + Network.State.Implemented + ", " + Network.State.Setup);
}
// don't allow clenaup=true for the network in Basic zone
DataCenter zone = _configMgr.getZone(network.getDataCenterId());
if (zone.getNetworkType() == NetworkType.Basic && cleanup) {
throw new InvalidParameterValueException("Cleanup can't be true when restart network in Basic zone");
}
_accountMgr.checkAccess(callerAccount, null, true, network);
boolean success = restartNetwork(networkId, callerAccount, callerUser, cleanup);
@ -3857,10 +3851,6 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
ReservationContext context = new ReservationContextImpl(null, null, callerUser, callerAccount);
if (cleanup) {
if (network.getGuestType() != GuestType.Isolated) {
s_logger.warn("Only support clean up network for isolated network!");
return false;
}
// shutdown the network
s_logger.debug("Shutting down the network id=" + networkId + " as a part of network restart");

View File

@ -1263,7 +1263,6 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
boolean isRedundant, Map<Param, Object> params) throws ConcurrentOperationException,
InsufficientCapacityException, ResourceUnavailableException {
List<DomainRouterVO> routers = new ArrayList<DomainRouterVO>();
Network lock = _networkDao.acquireInLockTable(guestNetwork.getId(), _networkMgr.getNetworkLockTimeout());
if (lock == null) {
@ -1285,73 +1284,111 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
boolean isPodBased = (dest.getDataCenter().getNetworkType() == NetworkType.Basic ||
_networkMgr.areServicesSupportedInNetwork(guestNetwork.getId(), Service.SecurityGroup))
&& guestNetwork.getTrafficType() == TrafficType.Guest;
Pair<DeploymentPlan, List<DomainRouterVO>> planAndRouters = getDeploymentPlanAndRouters(isPodBased, dest, guestNetwork.getId());
routers = planAndRouters.second();
// 2) Figure out required routers count
int routerCount = 1;
if (isRedundant) {
routerCount = 2;
// dest has pod=null, for Basic Zone findOrDeployVRs for all Pods
List<DeployDestination> destinations = new ArrayList<DeployDestination>();
if (dest.getDataCenter().getNetworkType() == NetworkType.Basic) {
// Find all pods in the data center with running or starting user vms
long dcId = dest.getDataCenter().getId();
List<HostPodVO> pods = _podDao.listByDataCenterIdVMTypeAndStates(dcId, VirtualMachine.Type.User, VirtualMachine.State.Starting, VirtualMachine.State.Running);
// Loop through all the pods skip those with running or starting VRs
for (HostPodVO pod: pods) {
// Get list of VRs in starting or running state
long podId = pod.getId();
List<DomainRouterVO> virtualRouters = _routerDao.listByPodIdAndStates(podId, VirtualMachine.State.Starting, VirtualMachine.State.Running);
assert (virtualRouters.size() <= 1) : "Pod can have utmost one VR in Basic Zone, please check!";
// Add virtualRouters to the routers, this avoids the situation when
// all routers are skipped and VirtualRouterElement throws exception
routers.addAll(virtualRouters);
// If List size is one, we already have a starting or running VR, skip deployment
if (virtualRouters.size() == 1) {
s_logger.debug("Skipping VR deployment: Found a running or starting VR in Pod "
+ pod.getName() + " id=" + podId);
continue;
}
// Add new DeployDestination for this pod
destinations.add(new DeployDestination(dest.getDataCenter(), pod, null, null));
}
}
/* If old network is redundant but new is single router, then routers.size() = 2 but routerCount = 1 */
if (routers.size() >= routerCount) {
return routers;
}
if (routers.size() >= 5) {
s_logger.error("Too much redundant routers!");
else {
// Else, just add the supplied dest
destinations.add(dest);
}
// Check if providers are supported in the physical networks
VirtualRouterProviderType type = VirtualRouterProviderType.VirtualRouter;
Long physicalNetworkId = _networkMgr.getPhysicalNetworkId(guestNetwork);
PhysicalNetworkServiceProvider provider = _physicalProviderDao.findByServiceProvider(physicalNetworkId, type.toString());
if (provider == null) {
throw new CloudRuntimeException("Cannot find service provider " + type.toString() + " in physical network " + physicalNetworkId);
}
VirtualRouterProvider vrProvider = _vrProviderDao.findByNspIdAndType(provider.getId(), type);
if (vrProvider == null) {
throw new CloudRuntimeException("Cannot find virtual router provider " + type.toString()+ " as service provider " + provider.getId());
}
// Except for Basic Zone, the for loop will iterate only once
for (DeployDestination destination: destinations) {
Pair<DeploymentPlan, List<DomainRouterVO>> planAndRouters = getDeploymentPlanAndRouters(isPodBased, destination, guestNetwork.getId());
routers = planAndRouters.second();
if (_networkMgr.isNetworkSystem(guestNetwork) || guestNetwork.getGuestType() == Network.GuestType.Shared) {
owner = _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM);
}
// 2) Figure out required routers count
int routerCount = 1;
if (isRedundant) {
routerCount = 2;
}
//Check if public network has to be set on VR
boolean publicNetwork = false;
if (_networkMgr.isProviderSupportServiceInNetwork(guestNetwork.getId(), Service.SourceNat, Provider.VirtualRouter)) {
publicNetwork = true;
}
if (isRedundant && !publicNetwork) {
s_logger.error("Didn't support redundant virtual router without public network!");
return null;
}
// If old network is redundant but new is single router, then routers.size() = 2 but routerCount = 1
if (routers.size() >= routerCount) {
return routers;
}
Long offeringId = _networkOfferingDao.findById(guestNetwork.getNetworkOfferingId()).getServiceOfferingId();
if (offeringId == null) {
offeringId = _offering.getId();
}
if (routers.size() >= 5) {
s_logger.error("Too much redundant routers!");
}
PublicIp sourceNatIp = null;
if (publicNetwork) {
sourceNatIp = _networkMgr.assignSourceNatIpAddressToGuestNetwork(owner, guestNetwork);
}
// Check if providers are supported in the physical networks
VirtualRouterProviderType type = VirtualRouterProviderType.VirtualRouter;
Long physicalNetworkId = _networkMgr.getPhysicalNetworkId(guestNetwork);
PhysicalNetworkServiceProvider provider = _physicalProviderDao.findByServiceProvider(physicalNetworkId, type.toString());
if (provider == null) {
throw new CloudRuntimeException("Cannot find service provider " + type.toString() + " in physical network " + physicalNetworkId);
}
VirtualRouterProvider vrProvider = _vrProviderDao.findByNspIdAndType(provider.getId(), type);
if (vrProvider == null) {
throw new CloudRuntimeException("Cannot find virtual router provider " + type.toString() + " as service provider " + provider.getId());
}
//3) deploy virtual router(s)
int count = routerCount - routers.size();
DeploymentPlan plan = planAndRouters.first();
for (int i = 0; i < count; i++) {
List<Pair<NetworkVO, NicProfile>> networks = createRouterNetworks(owner, isRedundant, plan, guestNetwork,
new Pair<Boolean, PublicIp>(publicNetwork, sourceNatIp));
//don't start the router as we are holding the network lock that needs to be released at the end of router allocation
DomainRouterVO router = deployRouter(owner, dest, plan, params, isRedundant, vrProvider, offeringId,
null, networks, false, null);
if (_networkMgr.isNetworkSystem(guestNetwork) || guestNetwork.getGuestType() == Network.GuestType.Shared) {
owner = _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM);
}
_routerDao.addRouterToGuestNetwork(router, guestNetwork);
routers.add(router);
// Check if public network has to be set on VR
boolean publicNetwork = false;
if (_networkMgr.isProviderSupportServiceInNetwork(guestNetwork.getId(), Service.SourceNat, Provider.VirtualRouter)) {
publicNetwork = true;
}
if (isRedundant && !publicNetwork) {
s_logger.error("Didn't support redundant virtual router without public network!");
return null;
}
Long offeringId = _networkOfferingDao.findById(guestNetwork.getNetworkOfferingId()).getServiceOfferingId();
if (offeringId == null) {
offeringId = _offering.getId();
}
PublicIp sourceNatIp = null;
if (publicNetwork) {
sourceNatIp = _networkMgr.assignSourceNatIpAddressToGuestNetwork(owner, guestNetwork);
}
// 3) deploy virtual router(s)
int count = routerCount - routers.size();
DeploymentPlan plan = planAndRouters.first();
for (int i = 0; i < count; i++) {
List<Pair<NetworkVO, NicProfile>> networks = createRouterNetworks(owner, isRedundant, plan, guestNetwork,
new Pair<Boolean, PublicIp>(publicNetwork, sourceNatIp));
//don't start the router as we are holding the network lock that needs to be released at the end of router allocation
DomainRouterVO router = deployRouter(owner, destination, plan, params, isRedundant, vrProvider, offeringId,
null, networks, false, null);
_routerDao.addRouterToGuestNetwork(router, guestNetwork);
routers.add(router);
}
}
} finally {
if (lock != null) {

View File

@ -61,7 +61,24 @@ public interface DomainRouterDao extends GenericDao<DomainRouterVO, Long> {
*/
public List<DomainRouterVO> listByHostId(Long hostId);
public List<DomainRouterVO> listByLastHostId(Long hostId);
/**
* list virtual machine routers by pod id. pass in null to get all
* virtual machine routers.
* @param podId id of the pod. null if to get all.
* @return list of DomainRouterVO
*/
public List<DomainRouterVO> listByPodId(Long podId);
/**
* list virtual machine routers by pod id. pass in null to get all
* virtual machine routers.
* @param podId id of the pod. null if to get all.
* @param state state of the domain router. null if to get all.
* @return list of DomainRouterVO
*/
public List<DomainRouterVO> listByPodIdAndStates(Long podId, State... states);
/**
* list virtual machine routers by host id.
* pass in null to get all

View File

@ -41,6 +41,7 @@ import com.cloud.utils.db.SearchCriteria.Op;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.db.UpdateBuilder;
import com.cloud.vm.DomainRouterVO;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachine.State;
@Local(value = { DomainRouterDao.class })
@ -66,6 +67,7 @@ public class DomainRouterDaoImpl extends GenericDaoBase<DomainRouterVO, Long> im
AllFieldsSearch.and("host", AllFieldsSearch.entity().getHostId(), Op.EQ);
AllFieldsSearch.and("lastHost", AllFieldsSearch.entity().getLastHostId(), Op.EQ);
AllFieldsSearch.and("state", AllFieldsSearch.entity().getState(), Op.EQ);
AllFieldsSearch.and("states", AllFieldsSearch.entity().getState(), Op.IN);
SearchBuilder<RouterNetworkVO> joinRouterNetwork = _routerNetworkDao.createSearchBuilder();
joinRouterNetwork.and("networkId", joinRouterNetwork.entity().getNetworkId(), Op.EQ);
AllFieldsSearch.join("networkRouter", joinRouterNetwork, joinRouterNetwork.entity().getRouterId(), AllFieldsSearch.entity().getId(), JoinType.INNER);
@ -177,6 +179,21 @@ public class DomainRouterDaoImpl extends GenericDaoBase<DomainRouterVO, Long> im
return listBy(sc);
}
@Override
public List<DomainRouterVO> listByPodId(Long podId) {
SearchCriteria<DomainRouterVO> sc = AllFieldsSearch.create();
sc.setParameters("podId", podId);
return listBy(sc);
}
@Override
public List<DomainRouterVO> listByPodIdAndStates(Long podId, State... states) {
SearchCriteria<DomainRouterVO> sc = AllFieldsSearch.create();
sc.setParameters("podId", podId);
sc.setParameters("states", (Object[]) states);
return listBy(sc);
}
@Override
public List<DomainRouterVO> listIsolatedByHostId(Long hostId) {
SearchCriteria<DomainRouterVO> sc = HostUpSearch.create();

View File

@ -46,7 +46,14 @@ public interface VMInstanceDao extends GenericDao<VMInstanceVO, Long>, StateDao<
* @return list of VMInstanceVO in the specified zone
*/
List<VMInstanceVO> listByZoneId(long zoneId);
/**
* List VMs by pod ID
* @param podId
* @return list of VMInstanceVO in the specified pod
*/
List<VMInstanceVO> listByPodId(long podId);
/**
* Lists non-expunged VMs by zone ID and templateId
* @param zoneId
@ -76,8 +83,8 @@ public interface VMInstanceDao extends GenericDao<VMInstanceVO, Long>, StateDao<
List<VMInstanceVO> listByZoneIdAndType(long zoneId, VirtualMachine.Type type);
List<VMInstanceVO> listUpByHostId(Long hostId);
List<VMInstanceVO> listByLastHostId(Long hostId);
List<VMInstanceVO> listByTypeAndState(State state, VirtualMachine.Type type);
List<VMInstanceVO> listByTypeAndState(VirtualMachine.Type type, State state);
List<VMInstanceVO> listByAccountId(long accountId);
public Long countAllocatedVirtualRoutersForAccount(long accountId);

View File

@ -230,14 +230,20 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
return listBy(sc);
}
@Override
public List<VMInstanceVO> listByPodId(long podId) {
SearchCriteria<VMInstanceVO> sc = AllFieldsSearch.create();
sc.setParameters("pod", podId);
return listBy(sc);
}
@Override
public List<VMInstanceVO> listByClusterId(long clusterId) {
SearchCriteria<VMInstanceVO> sc = VMClusterSearch.create();
sc.setJoinParameters("hostSearch", "clusterId", clusterId);
return listBy(sc);
}
@Override
public List<VMInstanceVO> listLHByClusterId(long clusterId) {
@ -309,7 +315,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
}
@Override
public List<VMInstanceVO> listByTypeAndState(State state, VirtualMachine.Type type) {
public List<VMInstanceVO> listByTypeAndState(VirtualMachine.Type type, State state) {
SearchCriteria<VMInstanceVO> sc = AllFieldsSearch.create();
sc.setParameters("type", type);
sc.setParameters("state", state);

View File

@ -699,15 +699,9 @@
success: function(json){
zoneObj = json.listzonesresponse.zone[0];
}
});
if(zoneObj.networktype == "Basic") {
args.$form.find('.form-item[rel=cleanup]').find('input').removeAttr('checked'); //unchecked
args.$form.find('.form-item[rel=cleanup]').hide(); //hidden
}
else {
args.$form.find('.form-item[rel=cleanup]').find('input').attr('checked', 'checked'); //checked
args.$form.find('.form-item[rel=cleanup]').css('display', 'inline-block'); //shown
}
});
args.$form.find('.form-item[rel=cleanup]').find('input').attr('checked', 'checked'); //checked
args.$form.find('.form-item[rel=cleanup]').css('display', 'inline-block'); //shown
},
fields: {
cleanup: {