package org.ovirt.engine.core.bll.storage.disk.image; import java.util.Map; import java.util.Optional; import javax.inject.Inject; import org.ovirt.engine.core.bll.InternalCommandAttribute; import org.ovirt.engine.core.bll.NonTransactiveCommandAttribute; import org.ovirt.engine.core.bll.context.CommandContext; import org.ovirt.engine.core.bll.storage.EntityPollingCommand; import org.ovirt.engine.core.bll.storage.StorageJobCommand; import org.ovirt.engine.core.bll.storage.utils.VdsCommandsHelper; import org.ovirt.engine.core.common.VdcObjectType; import org.ovirt.engine.core.common.action.ColdMergeCommandParameters; import org.ovirt.engine.core.common.action.FenceVolumeJobCommandParameters; import org.ovirt.engine.core.common.action.VdcActionParametersBase; import org.ovirt.engine.core.common.action.VdcActionType; import org.ovirt.engine.core.common.businessentities.HostJobInfo; import org.ovirt.engine.core.common.businessentities.SubchainInfo; import org.ovirt.engine.core.common.businessentities.VdsmImageLocationInfo; import org.ovirt.engine.core.common.businessentities.storage.DiskImage; import org.ovirt.engine.core.common.job.StepEnum; import org.ovirt.engine.core.common.vdscommands.ColdMergeVDSCommandParameters; import org.ovirt.engine.core.common.vdscommands.VDSCommandType; import org.ovirt.engine.core.dao.DiskImageDao; import org.ovirt.engine.core.dao.SnapshotDao; @NonTransactiveCommandAttribute @InternalCommandAttribute public class ColdMergeCommand<T extends ColdMergeCommandParameters> extends StorageJobCommand<T> implements EntityPollingCommand { @Inject private VdsmImagePoller poller; @Inject private DiskImageDao diskImageDao; @Inject private SnapshotDao snapshotDao; public ColdMergeCommand(T parameters, CommandContext cmdContext) { super(parameters, cmdContext); } @Override protected void executeCommand() { completeGenerationInfo(); VdsCommandsHelper.runVdsCommandWithFailover(VDSCommandType.ColdMerge, new ColdMergeVDSCommandParameters(getParameters().getStorageJobId(), getParameters().getSubchainInfo()), getParameters().getStoragePoolId(), this); setSucceeded(true); } @Override public HostJobInfo.HostJobStatus poll() { SubchainInfo info = getParameters().getSubchainInfo(); return poller.pollImage(getParameters().getStoragePoolId(), info.getStorageDomainId(), info.getImageGroupId(), info.getBaseImageId(), info.getBaseImageGeneration(), getCommandId(), getActionType()); } @Override public void attemptToFenceJob() { SubchainInfo info = getParameters().getSubchainInfo(); VdsmImageLocationInfo locationInfo = new VdsmImageLocationInfo(info.getStorageDomainId(), info.getImageGroupId(), info.getBaseImageId(), info.getBaseImageGeneration()); FenceVolumeJobCommandParameters parameters = new FenceVolumeJobCommandParameters(locationInfo); parameters.setParentCommand(getActionType()); parameters.setParentParameters(getParameters()); parameters.setStoragePoolId(getParameters().getStoragePoolId()); parameters.setEndProcedure(VdcActionParametersBase.EndProcedure.COMMAND_MANAGED); runInternalActionWithTasksContext(VdcActionType.FenceVolumeJob, parameters); } @Override public Map<String, String> getJobMessageProperties() { if (jobProperties == null) { DiskImage diskImage = diskImageDao.getSnapshotById(getParameters().getSubchainInfo().getTopImageId()); DiskImage destDiskImage = diskImageDao.getSnapshotById(getParameters().getSubchainInfo().getBaseImageId()); jobProperties = super.getJobMessageProperties(); jobProperties.put(VdcObjectType.Disk.name().toLowerCase(), diskImage.getDiskAlias()); jobProperties.put("sourcesnapshot", Optional.ofNullable(snapshotDao.get(diskImage.getVmSnapshotId()).getDescription()).orElse("")); jobProperties.put("destinationsnapshot", Optional.ofNullable(snapshotDao.get(destDiskImage.getVmSnapshotId()).getDescription()).orElse("")); } return jobProperties; } @Override public StepEnum getCommandStep() { return StepEnum.MERGE_SNAPSHOTS; } private void completeGenerationInfo() { SubchainInfo info = getParameters().getSubchainInfo(); DiskImage image = ImagesHandler.getVolumeInfoFromVdsm(getParameters().getStoragePoolId(), info.getStorageDomainId(), info.getImageGroupId(), info.getBaseImageId()); info.setBaseImageGeneration(image.getImage().getGeneration()); persistCommandIfNeeded(); } }