package org.ovirt.engine.core.bll; import org.ovirt.engine.core.bll.command.utils.StorageDomainSpaceChecker; import org.ovirt.engine.core.bll.interfaces.BackendInternal; import org.ovirt.engine.core.bll.storage.StorageDomainCommandBase; import org.ovirt.engine.core.common.AuditLogType; import org.ovirt.engine.core.common.action.MoveOrCopyImageGroupParameters; import org.ovirt.engine.core.common.action.MoveOrCopyParameters; import org.ovirt.engine.core.common.action.VdcActionParametersBase; import org.ovirt.engine.core.common.action.VdcActionType; import org.ovirt.engine.core.common.action.VdcReturnValueBase; import org.ovirt.engine.core.common.businessentities.DiskImage; import org.ovirt.engine.core.common.businessentities.DiskImageTemplate; import org.ovirt.engine.core.common.businessentities.ImageOperation; import org.ovirt.engine.core.common.businessentities.StorageDomainStatus; import org.ovirt.engine.core.common.businessentities.StoragePoolIsoMapId; import org.ovirt.engine.core.common.businessentities.VmTemplate; import org.ovirt.engine.core.common.businessentities.storage_domains; import org.ovirt.engine.core.common.queries.GetStorageDomainsByVmTemplateIdQueryParameters; import org.ovirt.engine.core.common.queries.VdcQueryType; import org.ovirt.engine.core.common.vdscommands.GetImageDomainsListVDSCommandParameters; import org.ovirt.engine.core.common.vdscommands.VDSCommandType; import org.ovirt.engine.core.compat.Guid; import org.ovirt.engine.core.compat.LogCompat; import org.ovirt.engine.core.compat.LogFactoryCompat; import org.ovirt.engine.core.dal.VdcBllMessages; import org.ovirt.engine.core.dal.dbbroker.DbFacade; import org.ovirt.engine.core.utils.transaction.TransactionMethod; import org.ovirt.engine.core.utils.transaction.TransactionSupport; public class MoveOrCopyTemplateCommand<T extends MoveOrCopyParameters> extends StorageDomainCommandBase<T> { /** * Constructor for command creation when compensation is applied on startup * * @param commandId */ protected MoveOrCopyTemplateCommand(Guid commandId) { super(commandId); } public MoveOrCopyTemplateCommand(T parameters) { super(parameters); setVmTemplateId(parameters.getContainerId()); parameters.setEntityId(getVmTemplateId()); } private storage_domains _sourceDomain; private Guid _sourceDomainId = new Guid(); protected storage_domains getSourceDomain() { if (_sourceDomain == null && !_sourceDomainId.equals(Guid.Empty)) { _sourceDomain = getStorageDomainDAO().getForStoragePool(_sourceDomainId, getStoragePool().getId()); } else if (_sourceDomain == null) { java.util.ArrayList<storage_domains> result = (java.util.ArrayList<storage_domains>) getBackend() .runInternalQuery(VdcQueryType.GetStorageDomainsByVmTemplateId, new GetStorageDomainsByVmTemplateIdQueryParameters(getVmTemplateId())).getReturnValue(); if (result != null) { for (storage_domains domain : result) { if (domain.getstatus() != null && domain.getstatus() == StorageDomainStatus.Active) { _sourceDomain = domain; } } } } return _sourceDomain; } protected BackendInternal getBackend() { return Backend.getInstance(); } protected void SetSourceDomainId(Guid storageId) { _sourceDomainId = storageId; } protected ImageOperation getMoveOrCopyImageOperation() { return ImageOperation.Copy; } private java.util.ArrayList<DiskImage> _templateDisks; protected java.util.ArrayList<DiskImage> getTemplateDisks() { if (_templateDisks == null && getVmTemplate() != null) { VmTemplateHandler.UpdateDisksFromDb(getVmTemplate()); _templateDisks = new java.util.ArrayList<DiskImage>(); for (DiskImageTemplate diTemplate : getVmTemplate().getDiskMap().values()) { _templateDisks.add(DbFacade.getInstance().getDiskImageDAO().getSnapshotById(diTemplate.getId())); } } return _templateDisks; } @Override protected boolean canDoAction() { boolean retValue = true; if (getVmTemplate() == null) { retValue = false; addCanDoActionMessage(VdcBllMessages.ACTION_TYPE_FAILED_TEMPLATE_DOES_NOT_EXIST); } else if (getTemplateDisks() == null || getTemplateDisks().size() <= 0) { addCanDoActionMessage(VdcBllMessages.TEMPLATE_IMAGE_NOT_EXIST); retValue = false; } // check that images are ok if (retValue && getSourceDomain() == null) { addCanDoActionMessage(VdcBllMessages.ACTION_TYPE_FAILED_STORAGE_DOMAIN_STATUS_ILLEGAL); retValue = false; } retValue = retValue && VmTemplateCommand.isVmTemplateImagesReady(getVmTemplateId(), getSourceDomain().getid(), getReturnValue().getCanDoActionMessages(), true, true, true, false); if (retValue) { setStoragePoolId(getVmTemplate().getstorage_pool_id()); retValue = CheckStorageDomain() && checkStorageDomainStatus(StorageDomainStatus.Active) && CheckIfDisksExist(getTemplateDisks()) && checkFreeSpaceOnDestinationDomain(getStorageDomain(), (int) getVmTemplate().getActualDiskSize()); } if (retValue && DbFacade.getInstance() .getStoragePoolIsoMapDAO() .get(new StoragePoolIsoMapId(getStorageDomain().getid(), getVmTemplate().getstorage_pool_id().getValue())) == null) { retValue = false; addCanDoActionMessage(VdcBllMessages.ACTION_TYPE_FAILED_STORAGE_POOL_NOT_MATCH); } if (!retValue) { if (getMoveOrCopyImageOperation() == ImageOperation.Move) { addCanDoActionMessage(VdcBllMessages.VAR__ACTION__MOVE); } else { addCanDoActionMessage(VdcBllMessages.VAR__ACTION__COPY); } addCanDoActionMessage(VdcBllMessages.VAR__TYPE__VM_TEMPLATE); } return retValue; } private boolean checkFreeSpaceOnDestinationDomain(storage_domains domain, int requestedSizeGB) { if (!StorageDomainSpaceChecker.hasSpaceForRequest(domain, requestedSizeGB)) { addCanDoActionMessage(VdcBllMessages.ACTION_TYPE_FAILED_DISK_SPACE_LOW); return false; } return true; } @Override protected void executeCommand() { if (VmTemplateHandler.isTemplateStatusIsNotLocked(getVmTemplateId())) { VmTemplateHandler.lockVmTemplateInTransaction(getVmTemplateId(), getCompensationContext()); MoveOrCopyAllImageGroups(); setSucceeded(true); } } protected void MoveOrCopyAllImageGroups() { MoveOrCopyAllImageGroups(getVmTemplateId(), getTemplateDisks()); } protected void MoveOrCopyAllImageGroups(final Guid containerID, final Iterable<DiskImage> disks) { TransactionSupport.executeInNewTransaction(new TransactionMethod<Void>() { @Override public Void runInTransaction() { for (DiskImage disk : disks) { MoveOrCopyImageGroupParameters tempVar = new MoveOrCopyImageGroupParameters(containerID, disk .getimage_group_id().getValue(), disk.getId(), getParameters().getStorageDomainId(), getMoveOrCopyImageOperation()); tempVar.setParentCommand(getActionType()); tempVar.setEntityId(getParameters().getEntityId()); tempVar.setAddImageDomainMapping(getMoveOrCopyImageOperation() == ImageOperation.Copy); MoveOrCopyImageGroupParameters p = tempVar; // if copying template then AddImageDomainMapping should be true if (getSourceDomain() != null) { p.setSourceDomainId(getSourceDomain().getid()); } p.setParentParemeters(getParameters()); VdcReturnValueBase vdcRetValue = getBackend().runInternalAction( VdcActionType.MoveOrCopyImageGroup, p); getParameters().getImagesParameters().add(p); getReturnValue().getTaskIdList().addAll(vdcRetValue.getInternalTaskIdList()); } return null; } }); } @Override public AuditLogType getAuditLogTypeValue() { switch (getActionState()) { case EXECUTE: return getSucceeded() ? (getMoveOrCopyImageOperation() == ImageOperation.Move) ? AuditLogType.USER_MOVED_TEMPLATE : AuditLogType.USER_COPIED_TEMPLATE : (getMoveOrCopyImageOperation() == ImageOperation.Move) ? AuditLogType.USER_FAILED_MOVE_TEMPLATE : AuditLogType.USER_FAILED_COPY_TEMPLATE; case END_SUCCESS: return getSucceeded() ? (getMoveOrCopyImageOperation() == ImageOperation.Move) ? AuditLogType.USER_MOVED_TEMPLATE_FINISHED_SUCCESS : AuditLogType.USER_COPIED_TEMPLATE_FINISHED_SUCCESS : (getMoveOrCopyImageOperation() == ImageOperation.Move) ? AuditLogType.USER_MOVED_TEMPLATE_FINISHED_FAILURE : AuditLogType.USER_COPIED_TEMPLATE_FINISHED_FAILURE; default: return (getMoveOrCopyImageOperation() == ImageOperation.Move) ? AuditLogType.USER_MOVED_TEMPLATE_FINISHED_FAILURE : AuditLogType.USER_COPIED_TEMPLATE_FINISHED_FAILURE; } } protected boolean CheckIfDisksExist(Iterable<DiskImage> disksList) { for (DiskImage disk : disksList) { java.util.ArrayList<Guid> domains = (java.util.ArrayList<Guid>) getBackend() .getResourceManager() .RunVdsCommand( VDSCommandType.GetImageDomainsList, new GetImageDomainsListVDSCommandParameters(disk.getstorage_pool_id().getValue(), disk .getimage_group_id().getValue())).getReturnValue(); if (domains.contains(getParameters().getStorageDomainId())) { addCanDoActionMessage(VdcBllMessages.ACTION_TYPE_FAILED_STORAGE_DOMAIN_ALREADY_CONTAINS_DISK); return false; } } return true; } protected void EndMoveOrCopyCommand() { EndActionOnAllImageGroups(); if (getVmTemplate() != null) { VmTemplateHandler.UnLockVmTemplate(getVmTemplateId()); UpdateTemplateInSpm(); } else { setCommandShouldBeLogged(false); log.warn("MoveOrCopyTemplateCommand::EndMoveOrCopyCommand: VmTemplate is null, not performing full EndAction"); } setSucceeded(true); } protected void UpdateTemplateInSpm() { VmTemplateCommand.UpdateTemplateInSpm(getVmTemplate().getstorage_pool_id().getValue(), new java.util.ArrayList<VmTemplate>(java.util.Arrays.asList(new VmTemplate[] { getVmTemplate() }))); } @Override protected void EndSuccessfully() { EndMoveOrCopyCommand(); } @Override protected void EndWithFailure() { EndMoveOrCopyCommand(); } protected void EndActionOnAllImageGroups() { for (VdcActionParametersBase p : getParameters().getImagesParameters()) { getBackend().EndAction(getImagesActionType(), p); } } protected VdcActionType getImagesActionType() { return VdcActionType.MoveOrCopyImageGroup; } private static LogCompat log = LogFactoryCompat.getLog(MoveOrCopyTemplateCommand.class); }