package org.ovirt.engine.core.bll.storage.disk.image; import java.util.ArrayList; import java.util.List; import javax.inject.Inject; import org.ovirt.engine.core.bll.NonTransactiveCommandAttribute; import org.ovirt.engine.core.bll.context.CommandContext; import org.ovirt.engine.core.bll.quota.QuotaConsumptionParameter; import org.ovirt.engine.core.bll.quota.QuotaStorageConsumptionParameter; import org.ovirt.engine.core.bll.quota.QuotaStorageDependent; import org.ovirt.engine.core.bll.tasks.CommandCoordinatorUtil; import org.ovirt.engine.core.bll.tasks.CommandHelper; import org.ovirt.engine.core.bll.utils.PermissionSubject; import org.ovirt.engine.core.bll.validator.storage.DiskImagesValidator; import org.ovirt.engine.core.bll.validator.storage.DiskValidator; import org.ovirt.engine.core.bll.validator.storage.StorageDomainValidator; import org.ovirt.engine.core.common.AuditLogType; import org.ovirt.engine.core.common.VdcObjectType; import org.ovirt.engine.core.common.action.AddDiskParameters; import org.ovirt.engine.core.common.action.TransferDiskImageParameters; import org.ovirt.engine.core.common.action.VdcActionType; import org.ovirt.engine.core.common.action.VdcReturnValueBase; import org.ovirt.engine.core.common.businessentities.ActionGroup; import org.ovirt.engine.core.common.businessentities.StorageDomain; import org.ovirt.engine.core.common.businessentities.storage.DiskImage; import org.ovirt.engine.core.common.utils.SizeConverter; import org.ovirt.engine.core.common.vdscommands.ImageActionsVDSCommandParameters; import org.ovirt.engine.core.common.vdscommands.PrepareImageVDSCommandParameters; import org.ovirt.engine.core.common.vdscommands.VDSCommandType; import org.ovirt.engine.core.common.vdscommands.VDSReturnValue; import org.ovirt.engine.core.compat.Guid; import org.ovirt.engine.core.dal.dbbroker.auditloghandling.AuditLogDirector; import org.ovirt.engine.core.dao.DiskDao; import org.ovirt.engine.core.dao.StorageDomainDao; import org.ovirt.engine.core.vdsbroker.vdsbroker.PrepareImageReturn; @NonTransactiveCommandAttribute public class TransferDiskImageCommand<T extends TransferDiskImageParameters> extends TransferImageCommand<T> implements QuotaStorageDependent { private static final String FILE_URL_SCHEME = "file://"; @Inject private AuditLogDirector auditLogDirector; @Inject private DiskDao diskDao; @Inject private StorageDomainDao storageDomainDao; public TransferDiskImageCommand(T parameters, CommandContext cmdContext) { super(parameters, cmdContext); } @Override protected boolean validateCreateImage() { VdcReturnValueBase returnValue = CommandHelper.validate(VdcActionType.AddDisk, getAddDiskParameters(), getContext().clone()); getReturnValue().setValidationMessages(returnValue.getValidationMessages()); return returnValue.isValid(); } @Override protected void createImage() { CommandCoordinatorUtil.executeAsyncCommand( VdcActionType.AddDisk, getAddDiskParameters(), cloneContextAndDetachFromParent()); } @Override protected String prepareImage(Guid vdsId) { VDSReturnValue vdsRetVal = runVdsCommand(VDSCommandType.PrepareImage, getPrepareParameters(vdsId)); return FILE_URL_SCHEME + ((PrepareImageReturn) vdsRetVal.getReturnValue()).getImagePath(); } @Override protected boolean validateImageTransfer(Guid imageId) { DiskImage diskImage = (DiskImage) diskDao.get(imageId); DiskValidator diskValidator = getDiskValidator(diskImage); DiskImagesValidator diskImagesValidator = getDiskImagesValidator(diskImage); StorageDomainValidator storageDomainValidator = getStorageDomainValidator( storageDomainDao.getForStoragePool(diskImage.getStorageIds().get(0), diskImage.getStoragePoolId())); return validate(diskValidator.isDiskExists()) && validate(diskValidator.isDiskAttachedToAnyVm()) && validate(diskImagesValidator.diskImagesNotIllegal()) && validate(diskImagesValidator.diskImagesNotLocked()) && validate(storageDomainValidator.isDomainExistAndActive()); } protected DiskImagesValidator getDiskImagesValidator(DiskImage diskImage) { return new DiskImagesValidator(diskImage); } protected DiskValidator getDiskValidator(DiskImage diskImage) { return new DiskValidator(diskImage); } protected StorageDomainValidator getStorageDomainValidator(StorageDomain storageDomain) { return new StorageDomainValidator(storageDomain); } private PrepareImageVDSCommandParameters getPrepareParameters(Guid vdsId) { return new PrepareImageVDSCommandParameters(vdsId, getStoragePool().getId(), getStorageDomainId(), getImage().getImage().getDiskId(), getImage().getImageId(), true); } @Override protected void tearDownImage(Guid vdsId) { VDSReturnValue vdsRetVal = runVdsCommand(VDSCommandType.TeardownImage, getImageActionsParameters(vdsId)); if (!vdsRetVal.getSucceeded()) { DiskImage image = (DiskImage) diskDao.get(getParameters().getImageId()); log.warn("Failed to tear down image '{}' for image transfer session: {}", image, vdsRetVal.getVdsError()); // Invoke log method directly rather than relying on infra, because teardown // failure may occur during command execution, e.g. if the upload is paused. addCustomValue("DiskAlias", image != null ? image.getDiskAlias() : "(unknown)"); auditLogDirector.log(this, AuditLogType.TRANSFER_IMAGE_TEARDOWN_FAILED); } } private AddDiskParameters getAddDiskParameters() { AddDiskParameters diskParameters = getParameters().getAddDiskParameters(); diskParameters.setParentCommand(getActionType()); diskParameters.setParentParameters(getParameters()); diskParameters.setShouldRemainIllegalOnFailedExecution(true); diskParameters.setSkipDomainCheck(true); return diskParameters; } protected ImageActionsVDSCommandParameters getImageActionsParameters(Guid vdsId) { return new ImageActionsVDSCommandParameters(vdsId, getStoragePool().getId(), getStorageDomainId(), getImage().getImage().getDiskId(), getImage().getImageId()); } @Override protected String getImageAlias() { return getParameters().getAddDiskParameters() != null ? getParameters().getAddDiskParameters().getDiskInfo().getDiskAlias() : getDiskImage().getDiskAlias(); } @Override protected String getImageType() { return "disk"; } @Override public List<QuotaConsumptionParameter> getQuotaStorageConsumptionParameters() { List<QuotaConsumptionParameter> list = new ArrayList<>(); if (getParameters().getAddDiskParameters() != null) { AddDiskParameters parameters = getAddDiskParameters(); list.add(new QuotaStorageConsumptionParameter( ((DiskImage) parameters.getDiskInfo()).getQuotaId(), null, QuotaConsumptionParameter.QuotaAction.CONSUME, getStorageDomainId(), (double) parameters.getDiskInfo().getSize() / SizeConverter.BYTES_IN_GB)); } return list; } @Override public List<PermissionSubject> getPermissionCheckSubjects() { List<PermissionSubject> listPermissionSubjects = new ArrayList<>(); if (isImageProvided()) { listPermissionSubjects.add(new PermissionSubject(getParameters().getImageId(), VdcObjectType.Disk, ActionGroup.EDIT_DISK_PROPERTIES)); } else { listPermissionSubjects.add(new PermissionSubject(getParameters().getStorageDomainId(), VdcObjectType.Storage, ActionGroup.CREATE_DISK)); } return listPermissionSubjects; } }