package org.ovirt.engine.core.bll.storage.disk.cinder; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.Map; import javax.inject.Inject; import org.ovirt.engine.core.bll.InternalCommandAttribute; import org.ovirt.engine.core.bll.context.CommandContext; import org.ovirt.engine.core.bll.storage.disk.AddDiskCommand; import org.ovirt.engine.core.bll.storage.disk.image.ImagesHandler; import org.ovirt.engine.core.bll.tasks.interfaces.CommandCallback; import org.ovirt.engine.core.common.VdcObjectType; import org.ovirt.engine.core.common.action.AddDiskParameters; import org.ovirt.engine.core.common.businessentities.SubjectEntity; import org.ovirt.engine.core.common.businessentities.storage.CinderDisk; import org.ovirt.engine.core.common.businessentities.storage.DiskImageDynamic; import org.ovirt.engine.core.common.businessentities.storage.ImageStatus; import org.ovirt.engine.core.common.businessentities.storage.ImageStorageDomainMap; import org.ovirt.engine.core.common.businessentities.storage.VolumeClassification; import org.ovirt.engine.core.common.businessentities.storage.VolumeFormat; import org.ovirt.engine.core.common.businessentities.storage.VolumeType; import org.ovirt.engine.core.common.utils.Pair; import org.ovirt.engine.core.compat.Guid; import org.ovirt.engine.core.dao.BaseDiskDao; import org.ovirt.engine.core.dao.DiskImageDynamicDao; import org.ovirt.engine.core.dao.ImageDao; import org.ovirt.engine.core.dao.ImageStorageDomainMapDao; import org.ovirt.engine.core.di.Injector; import org.ovirt.engine.core.utils.transaction.TransactionSupport; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @InternalCommandAttribute public class AddCinderDiskCommand<T extends AddDiskParameters> extends AddDiskCommand<T> { private static final Logger log = LoggerFactory.getLogger(AddCinderDiskCommand.class); @Inject private BaseDiskDao baseDiskDao; @Inject private ImageDao imageDao; @Inject private ImageStorageDomainMapDao imageStorageDomainMapDao; @Inject private DiskImageDynamicDao diskImageDynamicDao; public AddCinderDiskCommand(T parameters, CommandContext cmdContext) { super(parameters, cmdContext); } @Override public void executeCommand() { CinderDisk cinderDisk = createCinderDisk(); String volumeId = getCinderBroker().createDisk(cinderDisk); Guid volumeGuid = Guid.createGuidFromString(volumeId); cinderDisk.setId(volumeGuid); cinderDisk.setImageId(volumeGuid); getDiskVmElement().getId().setDeviceId(volumeGuid); cinderDisk.setVolumeClassification(VolumeClassification.Volume); addCinderDiskToDB(cinderDisk); getParameters().setDiskInfo(cinderDisk); persistCommand(getParameters().getParentCommand(), true); getReturnValue().setActionReturnValue(cinderDisk.getId()); setSucceeded(true); } protected void addCinderDiskToDB(final CinderDisk cinderDisk) { TransactionSupport.executeInNewTransaction(() -> { baseDiskDao.save(cinderDisk); imageDao.save(cinderDisk.getImage()); imageStorageDomainMapDao.save(new ImageStorageDomainMap(cinderDisk.getImageId(), cinderDisk.getStorageIds().get(0), cinderDisk.getQuotaId(), cinderDisk.getDiskProfileId())); DiskImageDynamic diskDynamic = new DiskImageDynamic(); diskDynamic.setId(cinderDisk.getImageId()); diskImageDynamicDao.save(diskDynamic); if (getVm() != null) { addDiskVmElementForDisk(getDiskVmElement()); addManagedDeviceForDisk(cinderDisk.getId()); } return null; }); } private CinderDisk createCinderDisk() { final CinderDisk cinderDisk = new CinderDisk(); cinderDisk.setDiskAlias(getDiskAlias()); cinderDisk.setSize(getParameters().getDiskInfo().getSize()); cinderDisk.setDiskAlias(getParameters().getDiskInfo().getDiskAlias()); cinderDisk.setDiskDescription(getParameters().getDiskInfo().getDiskDescription()); cinderDisk.setShareable(getParameters().getDiskInfo().isShareable()); cinderDisk.setStorageIds(new ArrayList<>(Arrays.asList(getParameters().getStorageDomainId()))); cinderDisk.setSize(getParameters().getDiskInfo().getSize()); cinderDisk.setVolumeType(VolumeType.Unassigned); cinderDisk.setVolumeFormat(VolumeFormat.RAW); cinderDisk.setCreationDate(new Date()); cinderDisk.setLastModified(new Date()); cinderDisk.setActive(true); cinderDisk.setImageStatus(ImageStatus.LOCKED); cinderDisk.setVmSnapshotId(getParameters().getVmSnapshotId()); cinderDisk.setCinderVolumeType(getParameters().getDiskInfo().getCinderVolumeType()); cinderDisk.setQuotaId(getParameters().getQuotaId()); if (getVm() != null) { cinderDisk.setDiskVmElements(Collections.singletonList(getDiskVmElement())); } return cinderDisk; } @Override protected void endSuccessfully() { super.endSuccessfully(); ImagesHandler.updateImageStatus(getDiskId(), ImageStatus.OK); auditLogDirector.log(this, getEndSuccessAuditLogTypeValue(true)); } @Override protected void endWithFailure() { super.endWithFailure(); ImagesHandler.updateImageStatus(getDiskId(), ImageStatus.ILLEGAL); auditLogDirector.log(this, getEndSuccessAuditLogTypeValue(false)); } private Guid getDiskId() { return getParameters().getDiskInfo().getId(); } @Override public boolean validate() { if (!validateQuota()){ return false; } if (getVm() != null) { return validateDiskVmData(); } return true; } @Override public CommandCallback getCallback() { return Injector.injectMembers(new AddCinderDiskCommandCallback()); } @Override protected Map<String, Pair<String, String>> getExclusiveLocks() { // The disk is already locked by the caller command (AddDiskCommand). return Collections.emptyMap(); } @Override protected Map<String, Pair<String, String>> getSharedLocks() { // The VM is already locked by the caller command (AddDiskCommand). return Collections.emptyMap(); } @Override protected Collection<SubjectEntity> getSubjectEntities() { return Collections.singleton(new SubjectEntity(VdcObjectType.Storage, getParameters().getStorageDomainId())); } }