Skip to content

Commit ffe2fa5

Browse files
authored
When VM is created and ROOT volume is created it should emit a VOLUME.CREATE event (#6939)
* When VM is created and ROOT volume is created it should emit a VOLUME.CREATE event Co-authored-by: Maxim Prokopchuk <mprokopchuk@apple.com>
1 parent 74623aa commit ffe2fa5

File tree

4 files changed

+73
-14
lines changed

4 files changed

+73
-14
lines changed

api/src/main/java/org/apache/cloudstack/context/CallContext.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,20 @@ public static CallContext register(String callingUserUuid, String callingAccount
223223
return register(user, account);
224224
}
225225

226+
/**
227+
* Register child CallContext.
228+
* @param parent - parent CallContext
229+
* @param eventResourceType - command resource type
230+
* @return Call context
231+
* @throws CloudAuthenticationException
232+
*/
233+
public static CallContext register(CallContext parent, ApiCommandResourceType eventResourceType) throws CloudAuthenticationException {
234+
CallContext callContext = register(parent.getCallingUserId(), parent.getCallingAccountId());
235+
callContext.setStartEventId(parent.getStartEventId());
236+
callContext.setEventResourceType(eventResourceType);
237+
return callContext;
238+
}
239+
226240
public static CallContext register(long callingUserId, long callingAccountId) throws CloudAuthenticationException {
227241
Account account = s_entityMgr.findById(Account.class, callingAccountId);
228242
if (account == null) {

engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
5050
import org.apache.cloudstack.annotation.AnnotationService;
5151
import org.apache.cloudstack.annotation.dao.AnnotationDao;
52+
import org.apache.cloudstack.api.ApiCommandResourceType;
5253
import org.apache.cloudstack.api.ApiConstants;
5354
import org.apache.cloudstack.api.command.admin.vm.MigrateVMCmd;
5455
import org.apache.cloudstack.api.command.admin.volume.MigrateVolumeCmdByAdmin;
@@ -485,16 +486,7 @@ public void doInTransactionWithoutResult(final TransactionStatus status) throws
485486
s_logger.debug("Allocating disks for " + vmFinal);
486487
}
487488

488-
String rootVolumeName = String.format("ROOT-%s", vmFinal.getId());
489-
if (template.getFormat() == ImageFormat.ISO) {
490-
volumeMgr.allocateRawVolume(Type.ROOT, rootVolumeName, rootDiskOfferingInfo.getDiskOffering(), rootDiskOfferingInfo.getSize(),
491-
rootDiskOfferingInfo.getMinIops(), rootDiskOfferingInfo.getMaxIops(), vmFinal, template, owner, null);
492-
} else if (template.getFormat() == ImageFormat.BAREMETAL) {
493-
s_logger.debug(String.format("%s has format [%s]. Skipping ROOT volume [%s] allocation.", template.toString(), ImageFormat.BAREMETAL, rootVolumeName));
494-
} else {
495-
volumeMgr.allocateTemplatedVolumes(Type.ROOT, rootVolumeName, rootDiskOfferingInfo.getDiskOffering(), rootDiskSizeFinal,
496-
rootDiskOfferingInfo.getMinIops(), rootDiskOfferingInfo.getMaxIops(), template, vmFinal, owner);
497-
}
489+
allocateRootVolume(vmFinal, template, rootDiskOfferingInfo, owner, rootDiskSizeFinal);
498490

499491
if (dataDiskOfferings != null) {
500492
for (final DiskOfferingInfo dataDiskOfferingInfo : dataDiskOfferings) {
@@ -521,6 +513,26 @@ public void doInTransactionWithoutResult(final TransactionStatus status) throws
521513
}
522514
}
523515

516+
private void allocateRootVolume(VMInstanceVO vm, VirtualMachineTemplate template, DiskOfferingInfo rootDiskOfferingInfo, Account owner, Long rootDiskSizeFinal) {
517+
// Create new Volume context and inject event resource type, id and details to generate VOLUME.CREATE event for the ROOT disk.
518+
CallContext volumeContext = CallContext.register(CallContext.current(), ApiCommandResourceType.Volume);
519+
try {
520+
String rootVolumeName = String.format("ROOT-%s", vm.getId());
521+
if (template.getFormat() == ImageFormat.ISO) {
522+
volumeMgr.allocateRawVolume(Type.ROOT, rootVolumeName, rootDiskOfferingInfo.getDiskOffering(), rootDiskOfferingInfo.getSize(),
523+
rootDiskOfferingInfo.getMinIops(), rootDiskOfferingInfo.getMaxIops(), vm, template, owner, null);
524+
} else if (template.getFormat() == ImageFormat.BAREMETAL) {
525+
s_logger.debug(String.format("%s has format [%s]. Skipping ROOT volume [%s] allocation.", template.toString(), ImageFormat.BAREMETAL, rootVolumeName));
526+
} else {
527+
volumeMgr.allocateTemplatedVolumes(Type.ROOT, rootVolumeName, rootDiskOfferingInfo.getDiskOffering(), rootDiskSizeFinal,
528+
rootDiskOfferingInfo.getMinIops(), rootDiskOfferingInfo.getMaxIops(), template, vm, owner);
529+
}
530+
} finally {
531+
// Remove volumeContext and pop vmContext back
532+
CallContext.unregister();
533+
}
534+
}
535+
524536
@Override
525537
public void allocate(final String vmInstanceName, final VirtualMachineTemplate template, final ServiceOffering serviceOffering,
526538
final LinkedHashMap<? extends Network, List<? extends NicProfile>> networks, final DeploymentPlan plan, final HypervisorType hyperType) throws InsufficientCapacityException {

engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,11 @@
3737
import javax.inject.Inject;
3838
import javax.naming.ConfigurationException;
3939

40+
import com.cloud.event.ActionEvent;
4041
import com.cloud.storage.StorageUtil;
42+
43+
import org.apache.cloudstack.api.ApiCommandResourceType;
44+
import org.apache.cloudstack.context.CallContext;
4145
import org.apache.cloudstack.secret.dao.PassphraseDao;
4246
import org.apache.cloudstack.secret.PassphraseVO;
4347
import org.apache.cloudstack.api.command.admin.vm.MigrateVMCmd;
@@ -135,6 +139,7 @@
135139
import com.cloud.utils.component.ManagerBase;
136140
import com.cloud.utils.db.DB;
137141
import com.cloud.utils.db.EntityManager;
142+
import com.cloud.utils.db.UUIDManager;
138143
import com.cloud.utils.db.Transaction;
139144
import com.cloud.utils.db.TransactionCallback;
140145
import com.cloud.utils.db.TransactionCallbackNoReturn;
@@ -176,6 +181,8 @@ public enum UserVmCloneType {
176181
@Inject
177182
EntityManager _entityMgr;
178183
@Inject
184+
private UUIDManager _uuidMgr;
185+
@Inject
179186
protected TemplateManager _tmpltMgr;
180187
@Inject
181188
protected VolumeDao _volsDao;
@@ -812,6 +819,7 @@ protected DiskProfile toDiskProfile(Volume vol, DiskOffering offering) {
812819
vol.getTemplateId());
813820
}
814821

822+
@ActionEvent(eventType = EventTypes.EVENT_VOLUME_CREATE, eventDescription = "creating ROOT volume", create = true)
815823
@Override
816824
public DiskProfile allocateRawVolume(Type type, String name, DiskOffering offering, Long size, Long minIops, Long maxIops, VirtualMachine vm, VirtualMachineTemplate template, Account owner,
817825
Long deviceId) {
@@ -871,7 +879,11 @@ public DiskProfile allocateRawVolume(Type type, String name, DiskOffering offeri
871879
_resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.volume, vol.isDisplayVolume());
872880
_resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.primary_storage, vol.isDisplayVolume(), new Long(vol.getSize()));
873881
}
874-
return toDiskProfile(vol, offering);
882+
DiskProfile diskProfile = toDiskProfile(vol, offering);
883+
884+
updateRootDiskVolumeEventDetails(type, vm, List.of(diskProfile));
885+
886+
return diskProfile;
875887
}
876888

877889
private DiskProfile allocateTemplatedVolume(Type type, String name, DiskOffering offering, Long rootDisksize, Long minIops, Long maxIops, VirtualMachineTemplate template, VirtualMachine vm,
@@ -953,6 +965,7 @@ private DiskProfile allocateTemplatedVolume(Type type, String name, DiskOffering
953965
return toDiskProfile(vol, offering);
954966
}
955967

968+
@ActionEvent(eventType = EventTypes.EVENT_VOLUME_CREATE, eventDescription = "creating ROOT volume", create = true)
956969
@Override
957970
public List<DiskProfile> allocateTemplatedVolumes(Type type, String name, DiskOffering offering, Long rootDisksize, Long minIops, Long maxIops, VirtualMachineTemplate template, VirtualMachine vm,
958971
Account owner) {
@@ -1006,10 +1019,32 @@ public List<DiskProfile> allocateTemplatedVolumes(Type type, String name, DiskOf
10061019
profiles.add(diskProfile);
10071020
}
10081021

1022+
updateRootDiskVolumeEventDetails(type, vm, profiles);
1023+
10091024
handleRootDiskControllerTpeForDeployAsIs(templateAsIsDisks, vm);
10101025
return profiles;
10111026
}
10121027

1028+
/**
1029+
* Set context information for VOLUME.CREATE event for ROOT disk.
1030+
*
1031+
* @param type - Volume Type
1032+
* @param vm - Virtual Machine
1033+
* @param diskProfiles - Disk Profiles
1034+
*/
1035+
private void updateRootDiskVolumeEventDetails(Type type, VirtualMachine vm, List<DiskProfile> diskProfiles) {
1036+
CallContext callContext = CallContext.current();
1037+
// Update only for volume type ROOT and API command resource type Volume
1038+
if (type == Type.ROOT && callContext != null && callContext.getEventResourceType() == ApiCommandResourceType.Volume) {
1039+
List<Long> volumeIds = diskProfiles.stream().map(DiskProfile::getVolumeId).filter(volumeId -> volumeId != null).collect(Collectors.toList());
1040+
if (!volumeIds.isEmpty()) {
1041+
callContext.setEventResourceId(volumeIds.get(0));
1042+
}
1043+
String volumeUuids = volumeIds.stream().map(volumeId -> this._uuidMgr.getUuid(Volume.class, volumeId)).collect(Collectors.joining(", "));
1044+
callContext.setEventDetails("Volume Id: " + volumeUuids + " Vm Id: " + this._uuidMgr.getUuid(VirtualMachine.class, vm.getId()));
1045+
}
1046+
}
1047+
10131048
private void handleRootDiskControllerTpeForDeployAsIs(List<DatadiskTO> disksAsIs, VirtualMachine vm) {
10141049
if (CollectionUtils.isNotEmpty(disksAsIs)) {
10151050
String diskControllerSubType = disksAsIs.get(0).getDiskControllerSubType();

server/src/main/java/com/cloud/vm/UserVmManagerImpl.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8099,14 +8099,12 @@ private void validateVolumes(List<VolumeVO> volumes) {
80998099
private void detachVolumesFromVm(List<VolumeVO> volumes) {
81008100

81018101
for (VolumeVO volume : volumes) {
8102-
CallContext vmContext = CallContext.current();
81038102
// Create new context and inject correct event resource type, id and details,
81048103
// otherwise VOLUME.DETACH event will be associated with VirtualMachine and contain VM id and other information.
8105-
CallContext volumeContext = CallContext.register(vmContext.getCallingUserId(), vmContext.getCallingAccountId());
8104+
CallContext volumeContext = CallContext.register(CallContext.current(), ApiCommandResourceType.Volume);
81068105
volumeContext.setEventDetails("Volume Id: " + this._uuidMgr.getUuid(Volume.class, volume.getId()) + " Vm Id: " + this._uuidMgr.getUuid(VirtualMachine.class, volume.getInstanceId()));
81078106
volumeContext.setEventResourceType(ApiCommandResourceType.Volume);
81088107
volumeContext.setEventResourceId(volume.getId());
8109-
volumeContext.setStartEventId(vmContext.getStartEventId());
81108108

81118109
Volume detachResult = null;
81128110
try {

0 commit comments

Comments
 (0)