1616// under the License.
1717package org .apache .cloudstack .network .lb ;
1818
19+ import static com .cloud .hypervisor .Hypervisor .HypervisorType .Hyperv ;
20+ import static com .cloud .hypervisor .Hypervisor .HypervisorType .KVM ;
21+ import static com .cloud .hypervisor .Hypervisor .HypervisorType .LXC ;
22+ import static com .cloud .hypervisor .Hypervisor .HypervisorType .VMware ;
23+ import static com .cloud .hypervisor .Hypervisor .HypervisorType .XenServer ;
24+
1925import java .util .ArrayList ;
2026import java .util .Arrays ;
2127import java .util .Iterator ;
3137import org .apache .cloudstack .framework .config .dao .ConfigurationDao ;
3238import org .apache .cloudstack .lb .ApplicationLoadBalancerRuleVO ;
3339import org .apache .cloudstack .lb .dao .ApplicationLoadBalancerRuleDao ;
40+ import org .apache .commons .collections .CollectionUtils ;
3441
3542import com .cloud .agent .AgentManager ;
3643import com .cloud .agent .api .Answer ;
118125import com .cloud .vm .dao .DomainRouterDao ;
119126import com .cloud .vm .dao .NicDao ;
120127
121- import static com .cloud .hypervisor .Hypervisor .HypervisorType .Hyperv ;
122- import static com .cloud .hypervisor .Hypervisor .HypervisorType .KVM ;
123- import static com .cloud .hypervisor .Hypervisor .HypervisorType .LXC ;
124- import static com .cloud .hypervisor .Hypervisor .HypervisorType .VMware ;
125- import static com .cloud .hypervisor .Hypervisor .HypervisorType .XenServer ;
126-
127128public class InternalLoadBalancerVMManagerImpl extends ManagerBase implements InternalLoadBalancerVMManager , InternalLoadBalancerVMService , VirtualMachineGuru {
128129 static final private String InternalLbVmNamePrefix = "b" ;
129130
@@ -732,6 +733,49 @@ public List<DomainRouterVO> findInternalLbVms(final long guestNetworkId, final I
732733 return internalLbVms ;
733734 }
734735
736+ protected String getRouterTemplateForHypervisor (HypervisorType hypervisorType , long dataCenterId ) {
737+ String templateName = null ;
738+ if (XenServer .equals (hypervisorType )) {
739+ templateName = VirtualNetworkApplianceManager .RouterTemplateXen .valueIn (dataCenterId );
740+ } else if (KVM .equals (hypervisorType )) {
741+ templateName = VirtualNetworkApplianceManager .RouterTemplateKvm .valueIn (dataCenterId );
742+ } else if (VMware .equals (hypervisorType )) {
743+ templateName = VirtualNetworkApplianceManager .RouterTemplateVmware .valueIn (dataCenterId );
744+ } else if (Hyperv .equals (hypervisorType )) {
745+ templateName = VirtualNetworkApplianceManager .RouterTemplateHyperV .valueIn (dataCenterId );
746+ } else if (LXC .equals (hypervisorType )) {
747+ templateName = VirtualNetworkApplianceManager .RouterTemplateLxc .valueIn (dataCenterId );
748+ }
749+ return templateName ;
750+ }
751+
752+ protected DomainRouterVO deployInternalLbVmWithTemplates (final long id , final DeploymentPlan plan , final long internalLbProviderId ,
753+ final Account owner , final long userId , final Long vpcId , final ServiceOffering routerOffering ,
754+ final LinkedHashMap <Network , List <? extends NicProfile >> networks ,
755+ final List <VMTemplateVO > templates ) throws InsufficientCapacityException {
756+ for (final Iterator <VMTemplateVO > templatesIterator = templates .iterator (); templatesIterator .hasNext ();) {
757+ final VMTemplateVO template = templatesIterator .next ();
758+ try {
759+ DomainRouterVO internalLbVm = new DomainRouterVO (id , routerOffering .getId (), internalLbProviderId ,
760+ VirtualMachineName .getSystemVmName (id , _instance , InternalLbVmNamePrefix ),
761+ template .getId (), template .getHypervisorType (), template .getGuestOSId (),
762+ owner .getDomainId (), owner .getId (), userId , false ,
763+ RedundantState .UNKNOWN , false , false , VirtualMachine .Type .InternalLoadBalancerVm , vpcId );
764+ internalLbVm .setRole (Role .INTERNAL_LB_VM );
765+ internalLbVm = _internalLbVmDao .persist (internalLbVm );
766+ _itMgr .allocate (internalLbVm .getInstanceName (), template , routerOffering , networks , plan , null );
767+ return _internalLbVmDao .findById (internalLbVm .getId ());
768+ } catch (InsufficientCapacityException ex ) {
769+ if (templatesIterator .hasNext ()) {
770+ logger .debug ("Failed to allocate the VR with hypervisor {} and {}, retrying with another template" , template .getHypervisorType (), template );
771+ } else {
772+ throw ex ;
773+ }
774+ }
775+ }
776+ return null ;
777+ }
778+
735779 protected DomainRouterVO deployInternalLbVm (final Account owner , final DeployDestination dest , final DeploymentPlan plan , final Map <Param , Object > params , final long internalLbProviderId ,
736780 final long svcOffId , final Long vpcId , final LinkedHashMap <Network , List <? extends NicProfile >> networks , final boolean startVm ) throws ConcurrentOperationException ,
737781 InsufficientAddressCapacityException , InsufficientServerCapacityException , InsufficientCapacityException , StorageUnavailableException ,
@@ -743,6 +787,14 @@ protected DomainRouterVO deployInternalLbVm(final Account owner, final DeployDes
743787 // Try to allocate the internal lb twice using diff hypervisors, and when failed both times, throw the exception up
744788 final List <HypervisorType > hypervisors = getHypervisors (dest , plan , null );
745789
790+ long userId = CallContext .current ().getCallingUserId ();
791+ if (CallContext .current ().getCallingAccount ().getId () != owner .getId ()) {
792+ List <UserVO > userVOs = _userDao .listByAccount (owner .getAccountId ());
793+ if (!userVOs .isEmpty ()) {
794+ userId = userVOs .get (0 ).getId ();
795+ }
796+ }
797+
746798 int allocateRetry = 0 ;
747799 int startRetry = 0 ;
748800 DomainRouterVO internalLbVm = null ;
@@ -751,45 +803,20 @@ protected DomainRouterVO deployInternalLbVm(final Account owner, final DeployDes
751803 try {
752804 final long id = _internalLbVmDao .getNextInSequence (Long .class , "id" );
753805 if (logger .isDebugEnabled ()) {
754- logger .debug ("Creating the internal lb vm " + id + " in datacenter " + dest .getDataCenter () + " with hypervisor type " + hType );
806+ logger .debug ("Creating the internal lb vm {} in datacenter {} with hypervisor type {}" ,
807+ id , dest .getDataCenter (), hType );
755808 }
756- String templateName = null ;
757- if (hType .equals (XenServer )) {
758- templateName = VirtualNetworkApplianceManager .RouterTemplateXen .valueIn (dest .getDataCenter ().getId ());
759- } else if (hType .equals (KVM )) {
760- templateName = VirtualNetworkApplianceManager .RouterTemplateKvm .valueIn (dest .getDataCenter ().getId ());
761- } else if (hType .equals (VMware )) {
762- templateName = VirtualNetworkApplianceManager .RouterTemplateVmware .valueIn (dest .getDataCenter ().getId ());
763- } else if (hType .equals (Hyperv )) {
764- templateName = VirtualNetworkApplianceManager .RouterTemplateHyperV .valueIn (dest .getDataCenter ().getId ());
765- } else if (hType .equals (LXC )) {
766- templateName = VirtualNetworkApplianceManager .RouterTemplateLxc .valueIn (dest .getDataCenter ().getId ());
767- }
768- final VMTemplateVO template = _templateDao .findRoutingTemplate (hType , templateName );
769-
770- if (template == null ) {
771- logger .debug (hType + " won't support system vm, skip it" );
809+ final String templateName = getRouterTemplateForHypervisor (hType , dest .getDataCenter ().getId ());
810+ final List <VMTemplateVO > templates = _templateDao .findRoutingTemplates (hType , templateName );
811+ if (CollectionUtils .isEmpty (templates )) {
812+ logger .debug ("{} won't support system vm, skip it" , hType );
772813 continue ;
773814 }
774-
775- long userId = CallContext .current ().getCallingUserId ();
776- if (CallContext .current ().getCallingAccount ().getId () != owner .getId ()) {
777- List <UserVO > userVOs = _userDao .listByAccount (owner .getAccountId ());
778- if (!userVOs .isEmpty ()) {
779- userId = userVOs .get (0 ).getId ();
780- }
781- }
782-
783- internalLbVm =
784- new DomainRouterVO (id , routerOffering .getId (), internalLbProviderId , VirtualMachineName .getSystemVmName (id , _instance , InternalLbVmNamePrefix ),
785- template .getId (), template .getHypervisorType (), template .getGuestOSId (), owner .getDomainId (), owner .getId (), userId , false , RedundantState .UNKNOWN , false , false , VirtualMachine .Type .InternalLoadBalancerVm , vpcId );
786- internalLbVm .setRole (Role .INTERNAL_LB_VM );
787- internalLbVm = _internalLbVmDao .persist (internalLbVm );
788- _itMgr .allocate (internalLbVm .getInstanceName (), template , routerOffering , networks , plan , null );
789- internalLbVm = _internalLbVmDao .findById (internalLbVm .getId ());
815+ internalLbVm = deployInternalLbVmWithTemplates (id , plan , internalLbProviderId , owner , userId , vpcId ,
816+ routerOffering , networks , templates );
790817 } catch (final InsufficientCapacityException ex ) {
791818 if (allocateRetry < 2 && iter .hasNext ()) {
792- logger .debug ("Failed to allocate the Internal lb vm with hypervisor type " + hType + " , retrying one more time" );
819+ logger .debug ("Failed to allocate the Internal lb vm with hypervisor type {} , retrying one more time" , hType );
793820 continue ;
794821 } else {
795822 throw ex ;
@@ -804,8 +831,7 @@ protected DomainRouterVO deployInternalLbVm(final Account owner, final DeployDes
804831 break ;
805832 } catch (final InsufficientCapacityException ex ) {
806833 if (startRetry < 2 && iter .hasNext ()) {
807- logger .debug ("Failed to start the Internal lb vm " + internalLbVm + " with hypervisor type " + hType + ", " +
808- "destroying it and recreating one more time" );
834+ logger .debug ("Failed to start the Internal lb vm {} with hypervisor type {}, destroying it and recreating one more time" , internalLbVm , hType );
809835 // destroy the internal lb vm
810836 destroyInternalLbVm (internalLbVm .getId (), _accountMgr .getSystemAccount (), User .UID_SYSTEM );
811837 continue ;
0 commit comments