diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index 292a25987ba..aee9a417b86 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -68,6 +68,7 @@ import com.cloud.dc.AccountVlanMapVO; import com.cloud.dc.DataCenter; import com.cloud.dc.DataCenter.NetworkType; import com.cloud.dc.DataCenterVO; +import com.cloud.dc.HostPodVO; import com.cloud.dc.Pod; import com.cloud.dc.PodVlanMapVO; import com.cloud.dc.Vlan; @@ -77,6 +78,7 @@ import com.cloud.dc.dao.AccountVlanMapDao; import com.cloud.dc.dao.DataCenterDao; import com.cloud.dc.dao.PodVlanMapDao; import com.cloud.dc.dao.VlanDao; +import com.cloud.dc.dao.HostPodDao; import com.cloud.deploy.DataCenterDeployment; import com.cloud.deploy.DeployDestination; import com.cloud.deploy.DeploymentPlan; @@ -202,6 +204,7 @@ import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.Ip; import com.cloud.utils.net.NetUtils; +import com.cloud.vm.DomainRouterVO; import com.cloud.vm.Nic; import com.cloud.vm.NicProfile; import com.cloud.vm.NicVO; @@ -232,6 +235,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag @Inject DataCenterDao _dcDao = null; @Inject + HostPodDao _podDao = null; + @Inject VlanDao _vlanDao = null; @Inject IPAddressDao _ipAddressDao = null; @@ -240,6 +245,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag @Inject DomainDao _domainDao = null; @Inject + DomainRouterDao _domainRouterDao = null; + @Inject UserStatisticsDao _userStatsDao = null; @Inject EventDao _eventDao = null; @@ -3807,12 +3814,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 +3858,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"); @@ -3873,14 +3870,43 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag s_logger.debug("Skip the shutting down of network id=" + networkId); } - // implement the network elements and rules again - DeployDestination dest = new DeployDestination(_dcDao.findById(network.getDataCenterId()), null, null, null); - s_logger.debug("Implementing the network " + network + " elements and resources as a part of network restart"); NetworkOfferingVO offering = _networkOfferingDao.findById(network.getNetworkOfferingId()); try { - implementNetworkElementsAndResources(dest, context, network, offering); + DataCenter dc = _dcDao.findById(network.getDataCenterId()); + //Pod based network restart for basic network, one VR per pod + if (dc.getNetworkType() == NetworkType.Basic) { + //Loop through all pods with running user vms and restart network + for (HostPodVO pod: _podDao.listByDataCenterId(dc.getId())) { + s_logger.debug("Trying to restart network for Pod: " + pod.getName() + ", id=" + pod.getId()); + //If cleanup is false, don't implement network on running VRs + List virtualRouters = _domainRouterDao.listByPodId(pod.getId()); + Boolean podHasSingleVR = (virtualRouters.size() == 1); + if (!podHasSingleVR) { + s_logger.warn("Pod should have only one VR in Basic Zone, please check!"); + } + if (!cleanup && virtualRouters != null && podHasSingleVR + && virtualRouters.get(0).getState() == VirtualMachine.State.Running) { + s_logger.debug("Cleanup=false: Found a running VR, skipping network implementation for the pod"); + continue; + } + //Implement network only if there are running user vms in 'pod' + List vms = _vmDao.listByPodId(pod.getId()); + for (VMInstanceVO vm: vms) { + // implement the network elements and rules again + if (vm.getType() == Type.User && vm.getState() == VirtualMachine.State.Running) { + DeployDestination dest = new DeployDestination(dc, pod, null, null); + implementNetworkElementsAndResources(dest, context, network, offering); + break; + } + } + } + } else { + // implement the network elements and rules again + DeployDestination dest = new DeployDestination(dc, null, null, null); + implementNetworkElementsAndResources(dest, context, network, offering); + } setRestartRequired(network, true); } catch (Exception ex) { s_logger.warn("Failed to implement network " + network + " elements and resources as a part of network restart due to ", ex); diff --git a/server/src/com/cloud/vm/dao/DomainRouterDao.java b/server/src/com/cloud/vm/dao/DomainRouterDao.java index 01e32588007..d8e8cd86f9a 100755 --- a/server/src/com/cloud/vm/dao/DomainRouterDao.java +++ b/server/src/com/cloud/vm/dao/DomainRouterDao.java @@ -61,7 +61,14 @@ public interface DomainRouterDao extends GenericDao { */ public List listByHostId(Long hostId); public List listByLastHostId(Long hostId); - + + /** + * 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 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..2948500a0d4 100755 --- a/server/src/com/cloud/vm/dao/DomainRouterDaoImpl.java +++ b/server/src/com/cloud/vm/dao/DomainRouterDaoImpl.java @@ -177,6 +177,13 @@ 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 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..9a261aa4116 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 diff --git a/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java b/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java index 571b5d1841c..7f1c5b2aa28 100644 --- a/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java +++ b/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java @@ -127,6 +127,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase implem AllFieldsSearch.and("lastHost", AllFieldsSearch.entity().getLastHostId(), Op.EQ); AllFieldsSearch.and("state", AllFieldsSearch.entity().getState(), Op.EQ); AllFieldsSearch.and("zone", AllFieldsSearch.entity().getDataCenterIdToDeployIn(), Op.EQ); + AllFieldsSearch.and("pod", AllFieldsSearch.entity().getPodIdToDeployIn(), Op.EQ); AllFieldsSearch.and("type", AllFieldsSearch.entity().getType(), Op.EQ); AllFieldsSearch.and("account", AllFieldsSearch.entity().getAccountId(), Op.EQ); AllFieldsSearch.done(); @@ -230,7 +231,14 @@ 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(); diff --git a/ui/scripts/network.js b/ui/scripts/network.js index d0f65c4c3c0..d239cad43a1 100644 --- a/ui/scripts/network.js +++ b/ui/scripts/network.js @@ -604,15 +604,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: {