package org.ovirt.engine.core.bll; import org.ovirt.engine.core.bll.context.CommandContext; import org.ovirt.engine.core.common.AuditLogType; import org.ovirt.engine.core.common.action.ShutdownVmParameters; import org.ovirt.engine.core.common.action.StopVmParameters; import org.ovirt.engine.core.common.action.StopVmTypeEnum; import org.ovirt.engine.core.common.action.VdcActionType; import org.ovirt.engine.core.common.businessentities.VMStatus; import org.ovirt.engine.core.common.config.Config; import org.ovirt.engine.core.common.config.ConfigValues; import org.ovirt.engine.core.common.errors.EngineMessage; import org.ovirt.engine.core.common.vdscommands.DestroyVmVDSCommandParameters; import org.ovirt.engine.core.common.vdscommands.VDSCommandType; import org.ovirt.engine.core.compat.Guid; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @NonTransactiveCommandAttribute(forceCompensation=true) public class ShutdownVmCommand<T extends ShutdownVmParameters> extends StopVmCommandBase<T> { private static final Logger log = LoggerFactory.getLogger(ShutdownVmCommand.class); protected ShutdownVmCommand(Guid commandId) { super(commandId); } public ShutdownVmCommand(T shutdownVmParamsData, CommandContext commandContext) { super(shutdownVmParamsData, commandContext); } @Override public AuditLogType getAuditLogTypeValue() { if (shouldSkipCommandExecutionCached()) { return logCommandExecutionSkipped("Shutdown VM"); } if (getSuspendedVm()) { return getSucceeded() ? AuditLogType.USER_STOP_SUSPENDED_VM : AuditLogType.USER_STOP_SUSPENDED_VM_FAILED; } else { return getSucceeded() ? AuditLogType.USER_INITIATED_SHUTDOWN_VM : AuditLogType.USER_FAILED_SHUTDOWN_VM; } } @Override protected void setActionMessageParameters() { addValidationMessage(EngineMessage.VAR__ACTION__SHUTDOWN); addValidationMessage(EngineMessage.VAR__TYPE__VM); } @Override protected void perform() { log.info("Entered (VM '{}').", getVm().getName()); vmHandler.updateVmGuestAgentVersion(getVm()); if (canShutdownVm()) { // shutting down desktop and waiting for it in a separate thread to // become 'down': log.info("Sending shutdown command for VM '{}'.", getVmName()); int secondsToWait = getParameters().getWaitBeforeShutdown() ? Config .<Integer> getValue(ConfigValues.VmGracefulShutdownTimeout) : 0; // sending a shutdown command to the VM: setActionReturnValue(runVdsCommand(VDSCommandType.DestroyVm, new DestroyVmVDSCommandParameters(getVdsId(), getVmId(), getParameters().getStopReason(), true, secondsToWait)) .getReturnValue()); } else { // cannot shutdown -> send a StopVm command instead ('destroy'): // don't log -> log will appear for the StopVmCommand we are about to run: setCommandShouldBeLogged(false); log.info("Cannot shutdown VM '{}', status is not up. Stopping instead.", getVmName()); StopVmParameters stopVmParams = new StopVmParameters(getVmId(), StopVmTypeEnum.CANNOT_SHUTDOWN); stopVmParams.setStopReason(getParameters().getStopReason()); // stopVmParams.ParametersCurrentUser = CurrentUser; stopVmParams.setSessionId(getParameters().getSessionId()); runInternalAction(VdcActionType.StopVm, stopVmParams); } setSucceeded(true); } private boolean canShutdownVm() { return getVm().getStatus() == VMStatus.Up && (Boolean.TRUE.equals(getVm().getAcpiEnable()) || getVm().getHasAgent()); } }