package io.cattle.platform.process.host;
import io.cattle.platform.async.utils.ResourceTimeoutException;
import io.cattle.platform.core.constants.CommonStatesConstants;
import io.cattle.platform.core.constants.HostConstants;
import io.cattle.platform.core.constants.MachineConstants;
import io.cattle.platform.core.model.Host;
import io.cattle.platform.core.model.PhysicalHost;
import io.cattle.platform.deferred.util.DeferredUtils;
import io.cattle.platform.engine.handler.HandlerResult;
import io.cattle.platform.engine.process.ProcessInstance;
import io.cattle.platform.engine.process.ProcessState;
import io.cattle.platform.eventing.EventService;
import io.cattle.platform.object.meta.ObjectMetaDataManager;
import io.cattle.platform.object.process.StandardProcess;
import io.cattle.platform.object.resource.ResourceMonitor;
import io.cattle.platform.object.resource.ResourcePredicate;
import io.cattle.platform.object.util.ObjectUtils;
import io.cattle.platform.object.util.TransitioningUtils;
import io.cattle.platform.process.base.AbstractDefaultProcessHandler;
import io.cattle.platform.util.exception.ExecutionException;
import javax.inject.Inject;
import javax.inject.Named;
@Named
public class HostProvision extends AbstractDefaultProcessHandler {
@Inject
ResourceMonitor resourceMonitor;
@Inject
EventService eventService;
@Override
public HandlerResult handle(ProcessState state, ProcessInstance process) {
final Host host = (Host)state.getResource();
PhysicalHost physicalHost = objectManager.loadResource(PhysicalHost.class, host.getPhysicalHostId());
if (physicalHost == null) {
return null;
}
physicalHost = resourceMonitor.waitFor(physicalHost, 5 * 60000, new ResourcePredicate<PhysicalHost>() {
@Override
public boolean evaluate(final PhysicalHost obj) {
boolean transitioning = objectMetaDataManager.isTransitioningState(obj.getClass(),
obj.getState());
if (!transitioning) {
return true;
}
objectManager.reload(host);
if (!host.getState().equals(HostConstants.STATE_PROVISIONING)) {
throw new ResourceTimeoutException(host, "provisioning canceled");
}
String message = TransitioningUtils.getTransitioningMessage(obj);
objectManager.setFields(host, ObjectMetaDataManager.TRANSITIONING_MESSAGE_FIELD, message);
DeferredUtils.nest(new Runnable() {
@Override
public void run() {
ObjectUtils.publishChanged(eventService, objectManager, host);
}
});
return false;
}
@Override
public String getMessage() {
return "machine to provision";
}
});
if (!CommonStatesConstants.ACTIVE.equals(physicalHost.getState())) {
objectProcessManager.scheduleStandardProcess(StandardProcess.ERROR, host, null);
String message = TransitioningUtils.getTransitioningMessage(physicalHost);
ExecutionException e = new ExecutionException(message);
e.setResources(host);
throw e;
}
try {
resourceMonitor.waitFor(host, 5 * 60000, new ResourcePredicate<Host>() {
@Override
public boolean evaluate(Host obj) {
if (!host.getState().equals(HostConstants.STATE_PROVISIONING)) {
throw new ResourceTimeoutException(host, "provisioning canceled");
}
return obj.getAgentId() != null;
}
@Override
public String getMessage() {
return "agent to check in";
}
});
} catch (ResourceTimeoutException rte) {
objectProcessManager.scheduleStandardProcess(StandardProcess.ERROR, host, null);
ExecutionException e = new ExecutionException(rte.getMessage());
e.setResources(host);
throw e;
}
return new HandlerResult(
MachineConstants.FIELD_DRIVER, physicalHost.getDriver()
).withChainProcessName(objectProcessManager.getProcessName(host, StandardProcess.ACTIVATE));
}
}