4141
4242import com .cloud .agent .api .PrepareForMigrationAnswer ;
4343import com .cloud .agent .api .to .DpdkTO ;
44+ import com .cloud .event .UsageEventVO ;
4445import com .cloud .offering .NetworkOffering ;
4546import com .cloud .offerings .dao .NetworkOfferingDetailsDao ;
4647import org .apache .cloudstack .affinity .dao .AffinityGroupVMMapDao ;
@@ -232,6 +233,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
232233
233234 private static final String VM_SYNC_ALERT_SUBJECT = "VM state sync alert" ;
234235
236+ @ Inject
237+ private UserVmManager _userVmMgr ;
235238 @ Inject
236239 private DataStoreManager dataStoreMgr ;
237240 @ Inject
@@ -3406,13 +3409,20 @@ public void checkIfCanUpgrade(final VirtualMachine vmInstance, final ServiceOffe
34063409 }
34073410
34083411 @ Override
3409- public boolean upgradeVmDb (final long vmId , final long serviceOfferingId ) {
3410- final VMInstanceVO vmForUpdate = _vmDao .createForUpdate ();
3411- vmForUpdate .setServiceOfferingId (serviceOfferingId );
3412- final ServiceOffering newSvcOff = _entityMgr .findById (ServiceOffering .class , serviceOfferingId );
3412+ public boolean upgradeVmDb (final long vmId , final ServiceOffering newServiceOffering , ServiceOffering currentServiceOffering ) {
3413+
3414+ final VMInstanceVO vmForUpdate = _vmDao .findById (vmId );
3415+ vmForUpdate .setServiceOfferingId (newServiceOffering .getId ());
3416+ final ServiceOffering newSvcOff = _entityMgr .findById (ServiceOffering .class , newServiceOffering .getId ());
34133417 vmForUpdate .setHaEnabled (newSvcOff .isOfferHA ());
34143418 vmForUpdate .setLimitCpuUse (newSvcOff .getLimitCpuUse ());
34153419 vmForUpdate .setServiceOfferingId (newSvcOff .getId ());
3420+ if (newServiceOffering .isDynamic ()) {
3421+ saveCustomOfferingDetails (vmId , newServiceOffering );
3422+ }
3423+ if (currentServiceOffering .isDynamic () && !newServiceOffering .isDynamic ()) {
3424+ removeCustomOfferingDetails (vmId );
3425+ }
34163426 return _vmDao .update (vmId , vmForUpdate );
34173427 }
34183428
@@ -4087,8 +4097,8 @@ public boolean unplugNic(final Network network, final NicTO nic, final VirtualMa
40874097 }
40884098
40894099 @ Override
4090- public VMInstanceVO reConfigureVm (final String vmUuid , final ServiceOffering oldServiceOffering ,
4091- final boolean reconfiguringOnExistingHost )
4100+ public VMInstanceVO reConfigureVm (final String vmUuid , final ServiceOffering oldServiceOffering , final ServiceOffering newServiceOffering ,
4101+ Map < String , String > customParameters , final boolean reconfiguringOnExistingHost )
40924102 throws ResourceUnavailableException , InsufficientServerCapacityException , ConcurrentOperationException {
40934103
40944104 final AsyncJobExecutionContext jobContext = AsyncJobExecutionContext .getCurrentExecutionContext ();
@@ -4098,14 +4108,14 @@ public VMInstanceVO reConfigureVm(final String vmUuid, final ServiceOffering old
40984108 final VirtualMachine vm = _vmDao .findByUuid (vmUuid );
40994109 placeHolder = createPlaceHolderWork (vm .getId ());
41004110 try {
4101- return orchestrateReConfigureVm (vmUuid , oldServiceOffering , reconfiguringOnExistingHost );
4111+ return orchestrateReConfigureVm (vmUuid , oldServiceOffering , newServiceOffering , reconfiguringOnExistingHost );
41024112 } finally {
41034113 if (placeHolder != null ) {
41044114 _workJobDao .expunge (placeHolder .getId ());
41054115 }
41064116 }
41074117 } else {
4108- final Outcome <VirtualMachine > outcome = reconfigureVmThroughJobQueue (vmUuid , oldServiceOffering , reconfiguringOnExistingHost );
4118+ final Outcome <VirtualMachine > outcome = reconfigureVmThroughJobQueue (vmUuid , oldServiceOffering , newServiceOffering , customParameters , reconfiguringOnExistingHost );
41094119
41104120 VirtualMachine vm = null ;
41114121 try {
@@ -4134,14 +4144,12 @@ public VMInstanceVO reConfigureVm(final String vmUuid, final ServiceOffering old
41344144 }
41354145 }
41364146
4137- private VMInstanceVO orchestrateReConfigureVm (final String vmUuid , final ServiceOffering oldServiceOffering , final boolean reconfiguringOnExistingHost ) throws ResourceUnavailableException ,
4138- ConcurrentOperationException {
4147+ private VMInstanceVO orchestrateReConfigureVm (final String vmUuid , final ServiceOffering oldServiceOffering , final ServiceOffering newServiceOffering ,
4148+ final boolean reconfiguringOnExistingHost ) throws ResourceUnavailableException , ConcurrentOperationException {
41394149 final VMInstanceVO vm = _vmDao .findByUuid (vmUuid );
4150+ upgradeVmDb (vm .getId (), newServiceOffering , oldServiceOffering );
41404151
4141- final long newServiceofferingId = vm .getServiceOfferingId ();
4142- final ServiceOffering newServiceOffering = _offeringDao .findById (vm .getId (), newServiceofferingId );
41434152 final HostVO hostVo = _hostDao .findById (vm .getHostId ());
4144-
41454153 final Float memoryOvercommitRatio = CapacityManager .MemOverprovisioningFactor .valueIn (hostVo .getClusterId ());
41464154 final Float cpuOvercommitRatio = CapacityManager .CpuOverprovisioningFactor .valueIn (hostVo .getClusterId ());
41474155 final long minMemory = (long )(newServiceOffering .getRamSize () / memoryOvercommitRatio );
@@ -4168,7 +4176,7 @@ private VMInstanceVO orchestrateReConfigureVm(final String vmUuid, final Service
41684176 if (reconfiguringOnExistingHost ) {
41694177 vm .setServiceOfferingId (oldServiceOffering .getId ());
41704178 _capacityMgr .releaseVmCapacity (vm , false , false , vm .getHostId ()); //release the old capacity
4171- vm .setServiceOfferingId (newServiceofferingId );
4179+ vm .setServiceOfferingId (newServiceOffering . getId () );
41724180 _capacityMgr .allocateVmCapacity (vm , false ); // lock the new capacity
41734181 }
41744182
@@ -4177,7 +4185,9 @@ private VMInstanceVO orchestrateReConfigureVm(final String vmUuid, final Service
41774185 s_logger .error ("Unable to scale vm due to " + (reconfigureAnswer == null ? "" : reconfigureAnswer .getDetails ()));
41784186 throw new CloudRuntimeException ("Unable to scale vm due to " + (reconfigureAnswer == null ? "" : reconfigureAnswer .getDetails ()));
41794187 }
4180-
4188+ if (vm .getType ().equals (VirtualMachine .Type .User )) {
4189+ _userVmMgr .generateUsageEvent (vm , vm .isDisplayVm (), EventTypes .EVENT_VM_DYNAMIC_SCALE );
4190+ }
41814191 success = true ;
41824192 } catch (final OperationTimedoutException e ) {
41834193 throw new AgentUnavailableException ("Operation timed out on reconfiguring " + vm , dstHostId );
@@ -4186,7 +4196,7 @@ private VMInstanceVO orchestrateReConfigureVm(final String vmUuid, final Service
41864196 } finally {
41874197 if (!success ) {
41884198 _capacityMgr .releaseVmCapacity (vm , false , false , vm .getHostId ()); // release the new capacity
4189- vm .setServiceOfferingId ( oldServiceOffering . getId ());
4199+ upgradeVmDb ( vm .getId (), oldServiceOffering , newServiceOffering ); // rollback
41904200 _capacityMgr .allocateVmCapacity (vm , false ); // allocate the old capacity
41914201 }
41924202 }
@@ -4195,6 +4205,33 @@ private VMInstanceVO orchestrateReConfigureVm(final String vmUuid, final Service
41954205
41964206 }
41974207
4208+ private void removeCustomOfferingDetails (long vmId ) {
4209+ Map <String , String > details = userVmDetailsDao .listDetailsKeyPairs (vmId );
4210+ details .remove (UsageEventVO .DynamicParameters .cpuNumber .name ());
4211+ details .remove (UsageEventVO .DynamicParameters .cpuSpeed .name ());
4212+ details .remove (UsageEventVO .DynamicParameters .memory .name ());
4213+ List <UserVmDetailVO > detailList = new ArrayList <UserVmDetailVO >();
4214+ for (Map .Entry <String , String > entry : details .entrySet ()) {
4215+ UserVmDetailVO detailVO = new UserVmDetailVO (vmId , entry .getKey (), entry .getValue (), true );
4216+ detailList .add (detailVO );
4217+ }
4218+ userVmDetailsDao .saveDetails (detailList );
4219+ }
4220+
4221+ private void saveCustomOfferingDetails (long vmId , ServiceOffering serviceOffering ) {
4222+ //save the custom values to the database.
4223+ Map <String , String > details = userVmDetailsDao .listDetailsKeyPairs (vmId );
4224+ details .put (UsageEventVO .DynamicParameters .cpuNumber .name (), serviceOffering .getCpu ().toString ());
4225+ details .put (UsageEventVO .DynamicParameters .cpuSpeed .name (), serviceOffering .getSpeed ().toString ());
4226+ details .put (UsageEventVO .DynamicParameters .memory .name (), serviceOffering .getRamSize ().toString ());
4227+ List <UserVmDetailVO > detailList = new ArrayList <UserVmDetailVO >();
4228+ for (Map .Entry <String , String > entry : details .entrySet ()) {
4229+ UserVmDetailVO detailVO = new UserVmDetailVO (vmId , entry .getKey (), entry .getValue (), true );
4230+ detailList .add (detailVO );
4231+ }
4232+ userVmDetailsDao .saveDetails (detailList );
4233+ }
4234+
41984235 @ Override
41994236 public String getConfigComponentName () {
42004237 return VirtualMachineManager .class .getSimpleName ();
@@ -5090,7 +5127,7 @@ public Outcome<VirtualMachine> removeVmFromNetworkThroughJobQueue(
50905127 }
50915128
50925129 public Outcome <VirtualMachine > reconfigureVmThroughJobQueue (
5093- final String vmUuid , final ServiceOffering newServiceOffering , final boolean reconfiguringOnExistingHost ) {
5130+ final String vmUuid , final ServiceOffering oldServiceOffering , final ServiceOffering newServiceOffering , Map < String , String > customParameters , final boolean reconfiguringOnExistingHost ) {
50945131
50955132 final CallContext context = CallContext .current ();
50965133 final User user = context .getCallingUser ();
@@ -5121,7 +5158,7 @@ public Outcome<VirtualMachine> reconfigureVmThroughJobQueue(
51215158
51225159 // save work context info (there are some duplications)
51235160 final VmWorkReconfigure workInfo = new VmWorkReconfigure (user .getId (), account .getId (), vm .getId (),
5124- VirtualMachineManagerImpl .VM_WORK_JOB_HANDLER , newServiceOffering .getId (), reconfiguringOnExistingHost );
5161+ VirtualMachineManagerImpl .VM_WORK_JOB_HANDLER , oldServiceOffering . getId (), newServiceOffering .getId (), customParameters , reconfiguringOnExistingHost );
51255162 workJob .setCmdInfo (VmWorkSerializer .serialize (workInfo ));
51265163
51275164 _jobMgr .submitAsyncJob (workJob , VmWorkConstants .VM_WORK_QUEUE , vm .getId ());
@@ -5280,10 +5317,14 @@ private Pair<JobInfo.Status, String> orchestrateReconfigure(final VmWorkReconfig
52805317 s_logger .info ("Unable to find vm " + work .getVmId ());
52815318 }
52825319 assert vm != null ;
5320+ ServiceOfferingVO oldServiceOffering = _offeringDao .findById (work .getOldServiceOfferingId ());
5321+ ServiceOfferingVO newServiceOffering = _offeringDao .findById (work .getNewServiceOfferingId ());
5322+ if (newServiceOffering .isDynamic ()) {
5323+ // update the service offering object with the custom parameters like cpu, memory
5324+ newServiceOffering = _offeringDao .getcomputeOffering (newServiceOffering , work .getCustomParameters ());
5325+ }
52835326
5284- final ServiceOffering newServiceOffering = _offeringDao .findById (vm .getId (), work .getNewServiceOfferingId ());
5285-
5286- reConfigureVm (vm .getUuid (), newServiceOffering ,
5327+ reConfigureVm (vm .getUuid (), oldServiceOffering , newServiceOffering , work .getCustomParameters (),
52875328 work .isSameHost ());
52885329 return new Pair <JobInfo .Status , String >(JobInfo .Status .SUCCEEDED , null );
52895330 }
0 commit comments