package org.ovirt.engine.core.vdsbroker;
import javax.inject.Inject;
import org.ovirt.engine.core.common.businessentities.VMStatus;
import org.ovirt.engine.core.common.businessentities.VmDynamic;
import org.ovirt.engine.core.common.vdscommands.DestroyVmVDSCommandParameters;
import org.ovirt.engine.core.common.vdscommands.VDSCommandType;
import org.ovirt.engine.core.common.vdscommands.VDSReturnValue;
import org.ovirt.engine.core.dao.VmDynamicDao;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DestroyVmVDSCommand<P extends DestroyVmVDSCommandParameters> extends ManagingVmCommand<P> {
private static final Logger log = LoggerFactory.getLogger(DestroyVmVDSCommand.class);
private static final long POWER_OFF_TIMEOUT_NANOSEC = 20000000000L; // 20 sec, in nanoseconds
@Inject
private VmDynamicDao vmDynamicDao;
public DestroyVmVDSCommand(P parameters) {
super(parameters);
}
@Override
protected void executeVDSCommand() {
resourceManager.removeAsyncRunningVm(getParameters().getVmId());
if (getParameters().getGracefully()) {
super.executeVDSCommand();
return;
}
long prevTimeout = resourceManager.getVmManager(getParameters().getVmId())
.setPowerOffTimeout(System.nanoTime() + POWER_OFF_TIMEOUT_NANOSEC);
VDSReturnValue vdsReturnValue = resourceManager.runVdsCommand(
VDSCommandType.Destroy,
getParameters());
if (!vdsReturnValue.getSucceeded()) {
resourceManager.getVmManager(getParameters().getVmId()).setPowerOffTimeout(prevTimeout);
if (vdsReturnValue.getExceptionObject() != null) {
logFailureToDestroy(vdsReturnValue);
getVDSReturnValue().setSucceeded(false);
getVDSReturnValue().setExceptionString(vdsReturnValue.getExceptionString());
getVDSReturnValue().setExceptionObject(vdsReturnValue.getExceptionObject());
getVDSReturnValue().setVdsError(vdsReturnValue.getVdsError());
}
}
}
@Override
protected void executeVmCommand() {
VDSReturnValue vdsReturnValue = resourceManager.runVdsCommand(
VDSCommandType.Destroy,
getParameters());
if (vdsReturnValue.getSucceeded()) {
VmDynamic vm = vmDynamicDao.get(getParameters().getVmId());
changeStatus(vm);
vm.setStopReason(getParameters().getReason());
vmManager.update(vm);
getVDSReturnValue().setReturnValue(vm.getStatus());
} else if (vdsReturnValue.getExceptionObject() != null) {
logFailureToDestroy(vdsReturnValue);
getVDSReturnValue().setSucceeded(false);
getVDSReturnValue().setExceptionString(vdsReturnValue.getExceptionString());
getVDSReturnValue().setExceptionObject(vdsReturnValue.getExceptionObject());
getVDSReturnValue().setVdsError(vdsReturnValue.getVdsError());
}
}
private void logFailureToDestroy(VDSReturnValue vdsReturnValue) {
log.error("Failed to destroy VM '{}' in VDS = '{}' , error = '{}'",
getParameters().getVmId(),
getParameters().getVdsId(),
vdsReturnValue.getExceptionString());
}
private void changeStatus(VmDynamic curVm) {
// do the state transition only if that VM is really running on SRC
if (getParameters().getVdsId().equals(curVm.getRunOnVds())) {
resourceManager.internalSetVmStatus(curVm, VMStatus.PoweringDown);
}
}
}