package org.ovirt.engine.core.bll.pm; import org.ovirt.engine.core.bll.NonTransactiveCommandAttribute; import org.ovirt.engine.core.bll.RestartVdsVmsOperation; import org.ovirt.engine.core.bll.context.CommandContext; import org.ovirt.engine.core.common.AuditLogType; import org.ovirt.engine.core.common.action.FenceVdsActionParameters; import org.ovirt.engine.core.common.action.LockProperties; import org.ovirt.engine.core.common.action.LockProperties.Scope; import org.ovirt.engine.core.common.action.VdcActionType; import org.ovirt.engine.core.common.businessentities.VDS; import org.ovirt.engine.core.common.businessentities.VDSStatus; import org.ovirt.engine.core.common.businessentities.pm.FenceActionType; import org.ovirt.engine.core.common.errors.EngineMessage; /** * Send a Start action to a power control device. * * This command should be run mutually exclusive from other fence actions to prevent same action or other fence actions * to clear the VMs and start them. * * @see RestartVdsCommand */ @NonTransactiveCommandAttribute public class StartVdsCommand<T extends FenceVdsActionParameters> extends FenceVdsBaseCommand<T> { public StartVdsCommand(T parameters, CommandContext commandContext) { super(parameters, commandContext); } @Override protected LockProperties applyLockProperties(LockProperties lockProperties) { return lockProperties.withScope(Scope.Execution); } @Override protected boolean validate() { boolean retValue = super.validate(); VDS vds = getVds(); if (vds != null) { VDSStatus vdsStatus = vds.getStatus(); if (vdsStatus == VDSStatus.Connecting) { retValue = false; addValidationMessage(EngineMessage.ACTION_TYPE_FAILED_VDS_INTERMITENT_CONNECTIVITY); } else if (!legalStatusForStartingVds(vdsStatus)) { addValidationMessage(EngineMessage.VDS_STATUS_NOT_VALID_FOR_START); retValue = false; log.error("VDS status for vds '{}' '{}' is '{}'", vds.getId(), vds.getName(), vdsStatus); } } return retValue; } protected boolean legalStatusForStartingVds(VDSStatus status) { return status == VDSStatus.Down || status == VDSStatus.NonResponsive || status == VDSStatus.Reboot || status == VDSStatus.Maintenance; } @Override protected void setStatus() { if (getParameters().isChangeHostToMaintenanceOnStart()) { setStatus(VDSStatus.Maintenance); } else { setStatus(VDSStatus.Reboot); } } @Override protected void setActionMessageParameters() { addValidationMessage(EngineMessage.VAR__ACTION__START); } @Override protected void handleError() { addValidationMessage(EngineMessage.VDS_FENCE_OPERATION_FAILED); addValidationMessage(EngineMessage.VAR__TYPE__HOST); addValidationMessage(EngineMessage.VAR__ACTION__START); log.error("Failed to run StartVdsCommand on host '{}'", getVdsName()); } @Override public AuditLogType getAuditLogTypeValue() { addValidationMessage(EngineMessage.VDS_FENCE_OPERATION_FAILED); addValidationMessage(EngineMessage.VAR__TYPE__HOST); addValidationMessage(EngineMessage.VAR__ACTION__START); return getSucceeded() ? AuditLogType.USER_VDS_START : AuditLogType.USER_FAILED_VDS_START; } @Override protected void handleSpecificCommandActions() { RestartVdsVmsOperation restartVmsOper = new RestartVdsVmsOperation( getContext(), getVds() ); restartVmsOper.restartVms(getVmList()); } @Override protected void freeLock() { if (getParameters().getParentCommand() != VdcActionType.RestartVds) { super.freeLock(); } } @Override protected FenceActionType getAction() { return FenceActionType.START; } @Override protected String getRequestedAuditEvent() { return AuditLogType.USER_VDS_STOP.name(); } @Override protected void setup() { // Set status immediately to prevent a race (BZ 636950/656224) // Skip setting status if action is manual Start and Host was in Maintenance if (getVds().getStatus() != VDSStatus.Maintenance) { setStatus(); } } @Override protected void teardown() { runSleepOnReboot(); } }