From d4d345a587dece2af171092d2d64f717ac957f49 Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Wed, 18 Jan 2012 11:21:04 -0800 Subject: [PATCH] Don't retry to re-create the vm when failed to allocate public ip --- .../com/cloud/network/rules/RulesManager.java | 3 +- .../cloud/network/rules/RulesManagerImpl.java | 69 +++++++++---------- .../src/com/cloud/vm/UserVmManagerImpl.java | 7 +- .../src/com/cloud/vm/VirtualMachineGuru.java | 4 +- .../cloud/vm/VirtualMachineManagerImpl.java | 7 +- 5 files changed, 48 insertions(+), 42 deletions(-) diff --git a/server/src/com/cloud/network/rules/RulesManager.java b/server/src/com/cloud/network/rules/RulesManager.java index 07ae211589f..ca97a7ea72c 100644 --- a/server/src/com/cloud/network/rules/RulesManager.java +++ b/server/src/com/cloud/network/rules/RulesManager.java @@ -19,6 +19,7 @@ package com.cloud.network.rules; import java.util.List; +import com.cloud.exception.InsufficientAddressCapacityException; import com.cloud.exception.NetworkRuleConflictException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.IpAddress; @@ -71,7 +72,7 @@ public interface RulesManager extends RulesService { boolean applyStaticNatsForNetwork(long networkId, boolean continueOnError, Account caller); - boolean enableElasticIpAndStaticNatForVm(UserVm vm, boolean stopOnError); + void enableElasticIpAndStaticNatForVm(UserVm vm) throws InsufficientAddressCapacityException; boolean disableStaticNat(long ipAddressId, Account caller, long callerUserId, boolean releaseIpIfElastic) throws ResourceUnavailableException; diff --git a/server/src/com/cloud/network/rules/RulesManagerImpl.java b/server/src/com/cloud/network/rules/RulesManagerImpl.java index ef1173c8b19..e599e0752b1 100755 --- a/server/src/com/cloud/network/rules/RulesManagerImpl.java +++ b/server/src/com/cloud/network/rules/RulesManagerImpl.java @@ -36,6 +36,7 @@ import com.cloud.event.EventTypes; import com.cloud.event.UsageEventVO; import com.cloud.event.dao.EventDao; import com.cloud.event.dao.UsageEventDao; +import com.cloud.exception.InsufficientAddressCapacityException; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.NetworkRuleConflictException; import com.cloud.exception.ResourceUnavailableException; @@ -1158,7 +1159,7 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { @Override - public boolean enableElasticIpAndStaticNatForVm(UserVm vm, boolean stopOnError) { + public void enableElasticIpAndStaticNatForVm(UserVm vm) throws InsufficientAddressCapacityException{ boolean success = true; //enable static nat if eIp capability is supported @@ -1167,43 +1168,39 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { Network guestNetwork = _networkMgr.getNetwork(nic.getNetworkId()); NetworkOffering offering = _configMgr.getNetworkOffering(guestNetwork.getNetworkOfferingId()); if (offering.getElasticIp()) { - try { - //check if there is already static nat enabled - if (_ipAddressDao.findByAssociatedVmId(vm.getId()) != null) { - s_logger.debug("Vm " + vm + " already has elastic ip associated with it in guest network " + guestNetwork); - continue; - } - - s_logger.debug("Allocating elastic ip and enabling static nat for it for the vm " + vm + " in guest network " + guestNetwork); - IpAddress ip = _networkMgr.assignElasticIp(guestNetwork.getId(), _accountMgr.getAccount(vm.getAccountId()), false, true); - if (ip == null) { - s_logger.warn("Failed to allocate elastic ip for vm " + vm + " in guest network " + guestNetwork); - return false; - } - s_logger.debug("Allocated elastic ip " + ip + ", now enabling static nat on it for vm " + vm); - try { - enableStaticNat(ip.getId(), vm.getId()); - } catch (Exception ex) { - s_logger.warn("Failed to enable static nat as a part of enabling elasticIp and staticNat for vm " + vm + " in guest network " + guestNetwork + " due to exception ", ex); - success = false; - } - if (!success) { - s_logger.warn("Failed to enable static nat on elastic ip " + ip + " for the vm " + vm + ", releasing the ip..."); - _networkMgr.handleElasticIpRelease(ip); - } else { - s_logger.warn("Succesfully enabled static nat on elastic ip " + ip + " for the vm " + vm); - } - } catch (Exception ex) { - s_logger.warn("Failed to acquire elastic ip and enable static nat for vm " + vm + " on the network " + guestNetwork + " due to exception ", ex); - } finally { - if (!success && stopOnError) { - return false; - } - } + + //check if there is already static nat enabled + if (_ipAddressDao.findByAssociatedVmId(vm.getId()) != null) { + s_logger.debug("Vm " + vm + " already has elastic ip associated with it in guest network " + guestNetwork); + continue; + } + + s_logger.debug("Allocating elastic ip and enabling static nat for it for the vm " + vm + " in guest network " + guestNetwork); + IpAddress ip = _networkMgr.assignElasticIp(guestNetwork.getId(), _accountMgr.getAccount(vm.getAccountId()), false, true); + if (ip == null) { + throw new CloudRuntimeException("Failed to allocate elastic ip for vm " + vm + " in guest network " + guestNetwork); + } + + s_logger.debug("Allocated elastic ip " + ip + ", now enabling static nat on it for vm " + vm); + + try { + enableStaticNat(ip.getId(), vm.getId()); + } catch (NetworkRuleConflictException ex) { + s_logger.warn("Failed to enable static nat as a part of enabling elasticIp and staticNat for vm " + vm + " in guest network " + guestNetwork + " due to exception ", ex); + success = false; + } catch (ResourceUnavailableException ex) { + s_logger.warn("Failed to enable static nat as a part of enabling elasticIp and staticNat for vm " + vm + " in guest network " + guestNetwork + " due to exception ", ex); + success = false; + } + + if (!success) { + s_logger.warn("Failed to enable static nat on elastic ip " + ip + " for the vm " + vm + ", releasing the ip..."); + _networkMgr.handleElasticIpRelease(ip); + } else { + s_logger.warn("Succesfully enabled static nat on elastic ip " + ip + " for the vm " + vm); + } } } - - return success; } } diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 66a834d226c..e05a699ea7d 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -102,6 +102,7 @@ import com.cloud.event.UsageEventVO; import com.cloud.event.dao.EventDao; import com.cloud.event.dao.UsageEventDao; import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientAddressCapacityException; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.ManagementServerException; @@ -2666,7 +2667,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager } @Override - public boolean finalizeStart(VirtualMachineProfile profile, long hostId, Commands cmds, ReservationContext context) { + public boolean finalizeStart(VirtualMachineProfile profile, long hostId, Commands cmds, ReservationContext context) throws InsufficientAddressCapacityException{ UserVmVO vm = profile.getVirtualMachine(); Answer[] answersToCmds = cmds.getAnswers(); @@ -2730,7 +2731,9 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager } //enable elastic ip for vm - return _rulesMgr.enableElasticIpAndStaticNatForVm(profile.getVirtualMachine(), true); + _rulesMgr.enableElasticIpAndStaticNatForVm(profile.getVirtualMachine()); + + return true; } @Override diff --git a/server/src/com/cloud/vm/VirtualMachineGuru.java b/server/src/com/cloud/vm/VirtualMachineGuru.java index 6799bbe392d..94981ca1d64 100644 --- a/server/src/com/cloud/vm/VirtualMachineGuru.java +++ b/server/src/com/cloud/vm/VirtualMachineGuru.java @@ -20,6 +20,7 @@ package com.cloud.vm; import com.cloud.agent.api.StopAnswer; import com.cloud.agent.manager.Commands; import com.cloud.deploy.DeployDestination; +import com.cloud.exception.InsufficientAddressCapacityException; import com.cloud.exception.ResourceUnavailableException; /** @@ -55,8 +56,9 @@ public interface VirtualMachineGuru { * @param profile virtual machine profile. * @param dest destination it was sent to. * @return true if deployment was fine; false if it didn't go well. + * @throws InsufficientAddressCapacityException */ - boolean finalizeStart(VirtualMachineProfile profile, long hostId, Commands cmds, ReservationContext context); + boolean finalizeStart(VirtualMachineProfile profile, long hostId, Commands cmds, ReservationContext context) throws InsufficientAddressCapacityException; boolean finalizeCommandsOnStart(Commands cmds, VirtualMachineProfile profile); diff --git a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java index 83046e4db38..8d1b0c84e9b 100755 --- a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -1999,7 +1999,10 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene } catch (ResourceUnavailableException e) { s_logger.error("Exception during update for running vm: " + vm, e); return null; - } catch (NoTransitionException e) { + }catch (InsufficientAddressCapacityException e) { + s_logger.error("Exception during update for running vm: " + vm, e); + return null; + }catch (NoTransitionException e) { s_logger.warn(e.getMessage()); } } @@ -2016,7 +2019,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene return command; } - private void ensureVmRunningContext(long hostId, VMInstanceVO vm, Event cause) throws OperationTimedoutException, ResourceUnavailableException, NoTransitionException { + private void ensureVmRunningContext(long hostId, VMInstanceVO vm, Event cause) throws OperationTimedoutException, ResourceUnavailableException, NoTransitionException, InsufficientAddressCapacityException { VirtualMachineGuru vmGuru = getVmGuru(vm); s_logger.debug("VM state is starting on full sync so updating it to running");