From 3386b902dfd4115c38bf257494a1ea6c53ab225c Mon Sep 17 00:00:00 2001 From: Sheng Yang Date: Tue, 14 Feb 2012 16:05:07 -0800 Subject: [PATCH] bug 13715: Modify changeCidr parameter of updateNetwork API We expect user to use following sequence when update virtual router provided network offering to external firewall devices offering: 1. Shutdown all the user VMs. 2. Modify network to new offering. 3. Click "Allow CIDR change" in the pop-up dialog, which would pass changeCidr=true to the updateNetwork API. We would shutdown guest network before we update the network for new offering(with changeCidr = true), in order to re-implement the network. status 13715: resolved fixed Reviewed-by: Alex --- .../src/com/cloud/network/NetworkManager.java | 2 +- .../com/cloud/network/NetworkManagerImpl.java | 48 +++++++++++++++---- .../cloud/network/MockNetworkManagerImpl.java | 2 +- 3 files changed, 40 insertions(+), 12 deletions(-) diff --git a/server/src/com/cloud/network/NetworkManager.java b/server/src/com/cloud/network/NetworkManager.java index e253a41aeac..431a9f0977e 100755 --- a/server/src/com/cloud/network/NetworkManager.java +++ b/server/src/com/cloud/network/NetworkManager.java @@ -163,7 +163,7 @@ public interface NetworkManager extends NetworkService { void prepareNicForMigration(VirtualMachineProfile vm, DeployDestination dest); - void shutdownNetwork(long networkId, ReservationContext context, boolean cleanupElements); + boolean shutdownNetwork(long networkId, ReservationContext context, boolean cleanupElements); boolean destroyNetwork(long networkId, ReservationContext context); diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index 2af5519cda5..d333a3b0ea4 100644 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -2807,18 +2807,19 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag @Override @DB - public void shutdownNetwork(long networkId, ReservationContext context, boolean cleanupElements) { - + public boolean shutdownNetwork(long networkId, ReservationContext context, boolean cleanupElements) { + boolean result = false; + Transaction txn = Transaction.currentTxn(); txn.start(); NetworkVO network = _networksDao.lockRow(networkId, true); if (network == null) { s_logger.debug("Unable to find network with id: " + networkId); - return; + return false; } if (network.getState() != Network.State.Implemented && network.getState() != Network.State.Shutdown) { s_logger.debug("Network is not implemented: " + network); - return; + return false; } network.setState(Network.State.Shutdown); @@ -2842,12 +2843,14 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag network.setRestartRequired(false); _networksDao.update(network.getId(), network); _networksDao.clearCheckForGc(networkId); - + result = true; } else { network.setState(Network.State.Implemented); _networksDao.update(network.getId(), network); + result = false; } txn.commit(); + return result; } private boolean shutdownNetworkElementsAndResources(ReservationContext context, boolean cleanupElements, NetworkVO network) { @@ -3849,6 +3852,12 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } } + private boolean checkForNonStoppedVmInNetwork(long networkId) { + List vms = _userVmDao.listByNetworkIdAndStates(networkId, VirtualMachine.State.Starting, + VirtualMachine.State.Running, VirtualMachine.State.Migrating, VirtualMachine.State.Stopping); + return vms.isEmpty(); + } + @Override @DB @ActionEvent(eventType = EventTypes.EVENT_NETWORK_UPDATE, eventDescription = "updating network", async = true) @@ -3912,6 +3921,11 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag && !changeCidr) { throw new InvalidParameterValueException("Can't guarantee guest network CIDR is unchanged after updating network!"); } + if (changeCidr) { + if (!checkForNonStoppedVmInNetwork(network.getId())) { + throw new InvalidParameterValueException("All user vm of network: " + network + " should be stopped before changing CIDR!"); + } + } // check if the network is upgradable if (!canUpgrade(network, oldNetworkOfferingId, networkOfferingId)) { throw new InvalidParameterValueException("Can't upgrade from network offering " + oldNetworkOfferingId + " to " + networkOfferingId + "; check logs for more information"); @@ -3956,11 +3970,21 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag boolean validStateToShutdown = (network.getState() == Network.State.Implemented || network.getState() == Network.State.Setup || network.getState() == Network.State.Allocated); if (restartNetwork) { if (validStateToShutdown) { - s_logger.debug("Shutting down elements and resources for network id=" + networkId + " as a part of network update"); + if (!changeCidr) { + s_logger.debug("Shutting down elements and resources for network id=" + networkId + " as a part of network update"); - if (!shutdownNetworkElementsAndResources(context, true, network)) { - s_logger.warn("Failed to shutdown the network elements and resources as a part of network restart: " + network); - throw new CloudRuntimeException("Failed to shutdown the network elements and resources as a part of network update: " + network); + if (!shutdownNetworkElementsAndResources(context, true, network)) { + s_logger.warn("Failed to shutdown the network elements and resources as a part of network restart: " + network); + throw new CloudRuntimeException("Failed to shutdown the network elements and resources as a part of network update: " + network); + } + } else { + // We need to shutdown the network, since we want to re-implement the network. + s_logger.debug("Shutting down network id=" + networkId + " as a part of network update"); + + if (!shutdownNetwork(network.getId(), context, true)) { + s_logger.warn("Failed to shutdown the network as a part of network update: " + network); + throw new CloudRuntimeException("Failed to shutdown the network as a part of network update: " + network); + } } } else { throw new CloudRuntimeException("Failed to shutdown the network elements and resources as a part of network update: " + network + "; network is in wrong state: " + network.getState()); @@ -4013,7 +4037,11 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag 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 update"); try { - implementNetworkElementsAndResources(dest, context, network, _networkOfferingDao.findById(network.getNetworkOfferingId())); + if (!changeCidr) { + implementNetworkElementsAndResources(dest, context, network, _networkOfferingDao.findById(network.getNetworkOfferingId())); + } else { + implementNetwork(network.getId(), dest, context); + } } catch (Exception ex) { s_logger.warn("Failed to implement network " + network + " elements and resources as a part of network update due to ", ex); throw new CloudRuntimeException("Failed to implement network " + network + " elements and resources as a part of network update"); diff --git a/server/test/com/cloud/network/MockNetworkManagerImpl.java b/server/test/com/cloud/network/MockNetworkManagerImpl.java index a09a5a7af94..5e050eee823 100755 --- a/server/test/com/cloud/network/MockNetworkManagerImpl.java +++ b/server/test/com/cloud/network/MockNetworkManagerImpl.java @@ -292,7 +292,7 @@ public class MockNetworkManagerImpl implements NetworkManager, Manager, NetworkS } @Override - public void shutdownNetwork(long networkId, ReservationContext context, boolean cleanupElements) { + public boolean shutdownNetwork(long networkId, ReservationContext context, boolean cleanupElements) { // TODO Auto-generated method stub }