diff --git a/server/src/com/cloud/dc/dao/HostPodDao.java b/server/src/com/cloud/dc/dao/HostPodDao.java index f031ac977e8..ced348425fd 100644 --- a/server/src/com/cloud/dc/dao/HostPodDao.java +++ b/server/src/com/cloud/dc/dao/HostPodDao.java @@ -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 { public List listByDataCenterId(long id); - - public HostPodVO findByName(String name, long dcId); + + public List listByDataCenterIdVMTypeAndStates(long id, VirtualMachine.Type type, VirtualMachine.State... states); + + public HostPodVO findByName(String name, long dcId); public HashMap> getCurrentPodCidrSubnets(long zoneId, long podIdToSkip); diff --git a/server/src/com/cloud/dc/dao/HostPodDaoImpl.java b/server/src/com/cloud/dc/dao/HostPodDaoImpl.java index bec8c518cdf..fce308aaa77 100644 --- a/server/src/com/cloud/dc/dao/HostPodDaoImpl.java +++ b/server/src/com/cloud/dc/dao/HostPodDaoImpl.java @@ -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 implements HostPodDao { @@ -61,7 +66,28 @@ public class HostPodDaoImpl extends GenericDaoBase implements H return listBy(sc); } - + + @Override + public List listByDataCenterIdVMTypeAndStates(long id, VirtualMachine.Type type, VirtualMachine.State... states) { + final VMInstanceDaoImpl _vmDao = ComponentLocator.inject(VMInstanceDaoImpl.class); + SearchBuilder vmInstanceSearch = _vmDao.createSearchBuilder(); + vmInstanceSearch.and("type", vmInstanceSearch.entity().getType(), SearchCriteria.Op.EQ); + vmInstanceSearch.and("states", vmInstanceSearch.entity().getState(), SearchCriteria.Op.IN); + + SearchBuilder 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 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 sc = DataCenterAndNameSearch.create(); diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index 7b38c836466..13a2bb1cbd1 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -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"); diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index 4400a9b52ad..dcb630e2895 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -1263,7 +1263,6 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian boolean isRedundant, Map params) throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { - List routers = new ArrayList(); 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> 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 destinations = new ArrayList(); + + 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 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 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> 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> networks = createRouterNetworks(owner, isRedundant, plan, guestNetwork, - new Pair(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> networks = createRouterNetworks(owner, isRedundant, plan, guestNetwork, + new Pair(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) { diff --git a/server/src/com/cloud/vm/dao/DomainRouterDao.java b/server/src/com/cloud/vm/dao/DomainRouterDao.java index 01e32588007..95d1ea6ca14 100755 --- a/server/src/com/cloud/vm/dao/DomainRouterDao.java +++ b/server/src/com/cloud/vm/dao/DomainRouterDao.java @@ -61,7 +61,24 @@ public interface DomainRouterDao extends GenericDao { */ public List listByHostId(Long hostId); public List 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 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 listByPodIdAndStates(Long podId, State... states); + /** * list virtual machine routers by host id. * pass in null to get all diff --git a/server/src/com/cloud/vm/dao/DomainRouterDaoImpl.java b/server/src/com/cloud/vm/dao/DomainRouterDaoImpl.java index 175d3f28d04..9ab3ad0f465 100755 --- a/server/src/com/cloud/vm/dao/DomainRouterDaoImpl.java +++ b/server/src/com/cloud/vm/dao/DomainRouterDaoImpl.java @@ -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 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 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 im return listBy(sc); } + @Override + public List listByPodId(Long podId) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("podId", podId); + return listBy(sc); + } + + @Override + public List listByPodIdAndStates(Long podId, State... states) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("podId", podId); + sc.setParameters("states", (Object[]) states); + return listBy(sc); + } + @Override public List listIsolatedByHostId(Long hostId) { SearchCriteria sc = HostUpSearch.create(); diff --git a/server/src/com/cloud/vm/dao/VMInstanceDao.java b/server/src/com/cloud/vm/dao/VMInstanceDao.java index 2cf3d75018c..8b0a523f56c 100644 --- a/server/src/com/cloud/vm/dao/VMInstanceDao.java +++ b/server/src/com/cloud/vm/dao/VMInstanceDao.java @@ -46,7 +46,14 @@ public interface VMInstanceDao extends GenericDao, StateDao< * @return list of VMInstanceVO in the specified zone */ List listByZoneId(long zoneId); - + + /** + * List VMs by pod ID + * @param podId + * @return list of VMInstanceVO in the specified pod + */ + List listByPodId(long podId); + /** * Lists non-expunged VMs by zone ID and templateId * @param zoneId @@ -76,8 +83,8 @@ public interface VMInstanceDao extends GenericDao, StateDao< List listByZoneIdAndType(long zoneId, VirtualMachine.Type type); List listUpByHostId(Long hostId); List listByLastHostId(Long hostId); - - List listByTypeAndState(State state, VirtualMachine.Type type); + + List listByTypeAndState(VirtualMachine.Type type, State state); List listByAccountId(long accountId); public Long countAllocatedVirtualRoutersForAccount(long accountId); diff --git a/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java b/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java index 571b5d1841c..85ad5d02e87 100644 --- a/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java +++ b/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java @@ -230,14 +230,20 @@ public class VMInstanceDaoImpl extends GenericDaoBase implem return listBy(sc); } - + + @Override + public List listByPodId(long podId) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("pod", podId); + return listBy(sc); + } + @Override public List listByClusterId(long clusterId) { SearchCriteria sc = VMClusterSearch.create(); sc.setJoinParameters("hostSearch", "clusterId", clusterId); return listBy(sc); } - @Override public List listLHByClusterId(long clusterId) { @@ -309,7 +315,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase implem } @Override - public List listByTypeAndState(State state, VirtualMachine.Type type) { + public List listByTypeAndState(VirtualMachine.Type type, State state) { SearchCriteria sc = AllFieldsSearch.create(); sc.setParameters("type", type); sc.setParameters("state", state); diff --git a/ui/scripts/network.js b/ui/scripts/network.js index 65adf666cb6..d3912a0dd4e 100644 --- a/ui/scripts/network.js +++ b/ui/scripts/network.js @@ -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: {