@@ -458,72 +458,79 @@ public void allocate(final String vmInstanceName, final VirtualMachineTemplate t
458458 throws InsufficientCapacityException {
459459
460460 s_logger .info (String .format ("allocating virtual machine from template:%s with hostname:%s and %d networks" , template .getUuid (), vmInstanceName , auxiliaryNetworks .size ()));
461+ VMInstanceVO persistedVm = null ;
462+ try {
463+ final VMInstanceVO vm = _vmDao .findVMByInstanceName (vmInstanceName );
464+ final Account owner = _entityMgr .findById (Account .class , vm .getAccountId ());
461465
462- final VMInstanceVO vm = _vmDao .findVMByInstanceName (vmInstanceName );
463- final Account owner = _entityMgr .findById (Account .class , vm .getAccountId ());
464-
465- if (s_logger .isDebugEnabled ()) {
466- s_logger .debug ("Allocating entries for VM: " + vm );
467- }
466+ if (s_logger .isDebugEnabled ()) {
467+ s_logger .debug ("Allocating entries for VM: " + vm );
468+ }
468469
469- vm .setDataCenterId (plan .getDataCenterId ());
470- if (plan .getPodId () != null ) {
471- vm .setPodIdToDeployIn (plan .getPodId ());
472- }
473- assert plan .getClusterId () == null && plan .getPoolId () == null : "We currently don't support cluster and pool preset yet" ;
474- final VMInstanceVO vmFinal = _vmDao .persist (vm );
470+ vm .setDataCenterId (plan .getDataCenterId ());
471+ if (plan .getPodId () != null ) {
472+ vm .setPodIdToDeployIn (plan .getPodId ());
473+ }
474+ assert plan .getClusterId () == null && plan .getPoolId () == null : "We currently don't support cluster and pool preset yet" ;
475+ persistedVm = _vmDao .persist (vm );
475476
476- final VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl (vmFinal , template , serviceOffering , null , null );
477+ final VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl (persistedVm , template , serviceOffering , null , null );
477478
478- Long rootDiskSize = rootDiskOfferingInfo .getSize ();
479- if (vm .getType ().isUsedBySystem () && SystemVmRootDiskSize .value () != null && SystemVmRootDiskSize .value () > 0L ) {
480- rootDiskSize = SystemVmRootDiskSize .value ();
481- }
482- final Long rootDiskSizeFinal = rootDiskSize ;
479+ Long rootDiskSize = rootDiskOfferingInfo .getSize ();
480+ if (vm .getType ().isUsedBySystem () && SystemVmRootDiskSize .value () != null && SystemVmRootDiskSize .value () > 0L ) {
481+ rootDiskSize = SystemVmRootDiskSize .value ();
482+ }
483+ final Long rootDiskSizeFinal = rootDiskSize ;
483484
484- Transaction .execute (new TransactionCallbackWithExceptionNoReturn <InsufficientCapacityException >() {
485- @ Override
486- public void doInTransactionWithoutResult (final TransactionStatus status ) throws InsufficientCapacityException {
487- if (s_logger .isDebugEnabled ()) {
488- s_logger .debug ("Allocating nics for " + vmFinal );
489- }
485+ if (s_logger .isDebugEnabled ()) {
486+ s_logger .debug ("Allocating nics for " + persistedVm );
487+ }
490488
491- try {
492- if (!vmProfile .getBootArgs ().contains ("ExternalLoadBalancerVm" )) {
493- _networkMgr .allocate (vmProfile , auxiliaryNetworks , extraDhcpOptions );
494- }
495- } catch (final ConcurrentOperationException e ) {
496- throw new CloudRuntimeException ("Concurrent operation while trying to allocate resources for the VM" , e );
489+ try {
490+ if (!vmProfile .getBootArgs ().contains ("ExternalLoadBalancerVm" )) {
491+ _networkMgr .allocate (vmProfile , auxiliaryNetworks , extraDhcpOptions );
497492 }
493+ } catch (final ConcurrentOperationException e ) {
494+ throw new CloudRuntimeException ("Concurrent operation while trying to allocate resources for the VM" , e );
495+ }
498496
499- if (s_logger .isDebugEnabled ()) {
500- s_logger .debug ("Allocating disks for " + vmFinal );
501- }
497+ if (s_logger .isDebugEnabled ()) {
498+ s_logger .debug ("Allocating disks for " + persistedVm );
499+ }
502500
503- allocateRootVolume (vmFinal , template , rootDiskOfferingInfo , owner , rootDiskSizeFinal );
501+ allocateRootVolume (persistedVm , template , rootDiskOfferingInfo , owner , rootDiskSizeFinal );
504502
505- if (dataDiskOfferings != null ) {
506- for (final DiskOfferingInfo dataDiskOfferingInfo : dataDiskOfferings ) {
507- volumeMgr .allocateRawVolume (Type .DATADISK , "DATA-" + vmFinal .getId (), dataDiskOfferingInfo .getDiskOffering (), dataDiskOfferingInfo .getSize (),
508- dataDiskOfferingInfo .getMinIops (), dataDiskOfferingInfo .getMaxIops (), vmFinal , template , owner , null );
509- }
503+ if (dataDiskOfferings != null ) {
504+ for (final DiskOfferingInfo dataDiskOfferingInfo : dataDiskOfferings ) {
505+ volumeMgr .allocateRawVolume (Type .DATADISK , "DATA-" + persistedVm .getId (), dataDiskOfferingInfo .getDiskOffering (), dataDiskOfferingInfo .getSize (),
506+ dataDiskOfferingInfo .getMinIops (), dataDiskOfferingInfo .getMaxIops (), persistedVm , template , owner , null );
510507 }
511- if ( datadiskTemplateToDiskOfferingMap != null && ! datadiskTemplateToDiskOfferingMap . isEmpty ()) {
512- int diskNumber = 1 ;
513- for ( Entry < Long , DiskOffering > dataDiskTemplateToDiskOfferingMap : datadiskTemplateToDiskOfferingMap . entrySet ()) {
514- DiskOffering diskOffering = dataDiskTemplateToDiskOfferingMap . getValue ();
515- long diskOfferingSize = diskOffering . getDiskSize () / ( 1024 * 1024 * 1024 );
516- VMTemplateVO dataDiskTemplate = _templateDao . findById ( dataDiskTemplateToDiskOfferingMap . getKey () );
517- volumeMgr . allocateRawVolume ( Type . DATADISK , "DATA-" + vmFinal . getId () + "-" + String . valueOf ( diskNumber ), diskOffering , diskOfferingSize , null , null ,
518- vmFinal , dataDiskTemplate , owner , Long . valueOf ( diskNumber ));
519- diskNumber ++ ;
520- }
508+ }
509+ if ( datadiskTemplateToDiskOfferingMap != null && ! datadiskTemplateToDiskOfferingMap . isEmpty ()) {
510+ int diskNumber = 1 ;
511+ for ( Entry < Long , DiskOffering > dataDiskTemplateToDiskOfferingMap : datadiskTemplateToDiskOfferingMap . entrySet ()) {
512+ DiskOffering diskOffering = dataDiskTemplateToDiskOfferingMap . getValue ( );
513+ long diskOfferingSize = diskOffering . getDiskSize () / ( 1024 * 1024 * 1024 );
514+ VMTemplateVO dataDiskTemplate = _templateDao . findById ( dataDiskTemplateToDiskOfferingMap . getKey ());
515+ volumeMgr . allocateRawVolume ( Type . DATADISK , "DATA-" + persistedVm . getId () + "-" + String . valueOf ( diskNumber ), diskOffering , diskOfferingSize , null , null ,
516+ persistedVm , dataDiskTemplate , owner , Long . valueOf ( diskNumber )) ;
517+ diskNumber ++;
521518 }
522519 }
523- });
524520
525- if (s_logger .isDebugEnabled ()) {
526- s_logger .debug ("Allocation completed for VM: " + vmFinal );
521+ if (s_logger .isDebugEnabled ()) {
522+ s_logger .debug ("Allocation completed for VM: " + persistedVm );
523+ }
524+ } catch (InsufficientCapacityException | CloudRuntimeException e ) {
525+ // Failed VM will be in Stopped. Transition it to Error, so it can be expunged by ExpungeTask or similar
526+ try {
527+ if (persistedVm != null ) {
528+ stateTransitTo (persistedVm , VirtualMachine .Event .OperationFailedToError , null );
529+ }
530+ } catch (NoTransitionException nte ) {
531+ s_logger .error (String .format ("Failed to transition %s in %s state to Error state" , persistedVm , persistedVm .getState ().toString ()));
532+ }
533+ throw e ;
527534 }
528535 }
529536
0 commit comments