use of org.eclipse.che.api.core.model.machine.MachineSource in project che by eclipse.
the class CheEnvironmentEngine method startEnvironmentQueue.
/**
* Starts all machine from machine queue of environment.
*/
private void startEnvironmentQueue(String namespace, String workspaceId, String devMachineName, String networkId, boolean recover, MachineStartedHandler startedHandler) throws ServerException, EnvironmentException {
// Starting all machines in environment one by one by getting configs
// from the corresponding starting queue.
// Config will be null only if there are no machines left in the queue
String envName;
MessageConsumer<MachineLogMessage> envLogger;
String creator = EnvironmentContext.getCurrent().getSubject().getUserId();
try (@SuppressWarnings("unused") Unlocker u = stripedLocks.readLock(workspaceId)) {
EnvironmentHolder environmentHolder = environments.get(workspaceId);
if (environmentHolder == null) {
throw new ServerException("Environment start is interrupted.");
}
envName = environmentHolder.name;
envLogger = environmentHolder.logger;
}
try {
machineProvider.createNetwork(networkId);
String machineName = queuePeekOrFail(workspaceId);
while (machineName != null) {
boolean isDev = devMachineName.equals(machineName);
// Environment start is failed when any machine start is failed, so if any error
// occurs during machine creation then environment start fail is reported and
// start resources such as queue and descriptor must be cleaned up
CheServiceImpl service;
@Nullable ExtendedMachine extendedMachine;
try (@SuppressWarnings("unused") Unlocker u = stripedLocks.readLock(workspaceId)) {
EnvironmentHolder environmentHolder = environments.get(workspaceId);
if (environmentHolder == null) {
throw new ServerException("Environment start is interrupted.");
}
service = environmentHolder.environment.getServices().get(machineName);
extendedMachine = environmentHolder.environmentConfig.getMachines().get(machineName);
}
// should not happen
if (service == null) {
LOG.error("Start of machine with name {} in workspace {} failed. Machine not found in start queue", machineName, workspaceId);
throw new ServerException(format("Environment of workspace with ID '%s' failed due to internal error", workspaceId));
}
final String finalMachineName = machineName;
// needed to reuse startInstance method and
// create machine instances by different implementation-specific providers
MachineStarter machineStarter = (machineLogger, machineSource) -> {
CheServiceImpl serviceWithNormalizedSource = normalizeServiceSource(service, machineSource);
return machineProvider.startService(namespace, workspaceId, envName, finalMachineName, isDev, networkId, serviceWithNormalizedSource, machineLogger);
};
MachineImpl machine = MachineImpl.builder().setConfig(MachineConfigImpl.builder().setDev(isDev).setLimits(new MachineLimitsImpl(bytesToMB(service.getMemLimit()))).setType("docker").setName(machineName).setEnvVariables(service.getEnvironment()).build()).setId(service.getId()).setWorkspaceId(workspaceId).setStatus(MachineStatus.CREATING).setEnvName(envName).setOwner(creator).build();
checkInterruption(workspaceId, envName);
Instance instance = startInstance(recover, envLogger, machine, machineStarter);
checkInterruption(workspaceId, envName);
startedHandler.started(instance, extendedMachine);
checkInterruption(workspaceId, envName);
// Machine destroying is an expensive operation which must be
// performed outside of the lock, this section checks if
// the environment wasn't stopped while it is starting and sets
// polled flag to true if the environment wasn't stopped.
// Also polls the proceeded machine configuration from the queue
boolean queuePolled = false;
try (@SuppressWarnings("unused") Unlocker u = stripedLocks.writeLock(workspaceId)) {
ensurePreDestroyIsNotExecuted();
EnvironmentHolder environmentHolder = environments.get(workspaceId);
if (environmentHolder != null) {
final Queue<String> queue = environmentHolder.startQueue;
if (queue != null) {
queue.poll();
queuePolled = true;
}
}
}
// must be destroyed
if (!queuePolled) {
try {
eventService.publish(newDto(MachineStatusEvent.class).withEventType(MachineStatusEvent.EventType.DESTROYING).withDev(isDev).withMachineName(machineName).withMachineId(instance.getId()).withWorkspaceId(workspaceId));
instance.destroy();
removeMachine(workspaceId, instance.getId());
eventService.publish(newDto(MachineStatusEvent.class).withEventType(MachineStatusEvent.EventType.DESTROYED).withDev(isDev).withMachineName(machineName).withMachineId(instance.getId()).withWorkspaceId(workspaceId));
} catch (MachineException e) {
LOG.error(e.getLocalizedMessage(), e);
}
throw new ServerException("Workspace '" + workspaceId + "' start interrupted. Workspace stopped before all its machines started");
}
machineName = queuePeekOrFail(workspaceId);
}
} catch (RuntimeException | ServerException | EnvironmentStartInterruptedException e) {
boolean interrupted = Thread.interrupted();
EnvironmentHolder env;
try (@SuppressWarnings("unused") Unlocker u = stripedLocks.writeLock(workspaceId)) {
env = environments.remove(workspaceId);
}
try {
destroyEnvironment(env.networkId, env.machines);
} catch (Exception remEx) {
LOG.error(remEx.getLocalizedMessage(), remEx);
}
if (interrupted) {
throw new EnvironmentStartInterruptedException(workspaceId, envName);
}
try {
throw e;
} catch (ServerException | EnvironmentStartInterruptedException rethrow) {
throw rethrow;
} catch (Exception wrap) {
throw new ServerException(wrap.getMessage(), wrap);
}
}
}
use of org.eclipse.che.api.core.model.machine.MachineSource in project che by eclipse.
the class DockerInstanceTest method shouldSaveDockerInstanceStateIntoRepository.
@Test
public void shouldSaveDockerInstanceStateIntoRepository() throws Exception {
final String digest = "image12";
dockerInstance = getDockerInstance(getMachine(), REGISTRY, CONTAINER, IMAGE, true);
when(dockerConnectorMock.push(any(PushParams.class), any(ProgressMonitor.class))).thenReturn(digest);
final MachineSource result = dockerInstance.saveToSnapshot();
assertTrue(result instanceof DockerMachineSource);
DockerMachineSource dockerMachineSource = (DockerMachineSource) result;
assertEquals(dockerMachineSource.getTag(), TAG);
assertEquals(dockerMachineSource.getDigest(), digest);
assertEquals(dockerMachineSource.getRegistry(), REGISTRY);
}
use of org.eclipse.che.api.core.model.machine.MachineSource in project che by eclipse.
the class DockerInstanceTest method shouldSaveDockerInstanceStateIntoLocalImage.
@Test
public void shouldSaveDockerInstanceStateIntoLocalImage() throws Exception {
final MachineSource result = dockerInstance.saveToSnapshot();
assertTrue(result instanceof DockerMachineSource);
DockerMachineSource dockerMachineSource = (DockerMachineSource) result;
assertEquals(dockerMachineSource.getTag(), TAG);
assertNotNull(dockerMachineSource.getRepository());
assertEquals(dockerMachineSource.getRegistry(), null);
}
use of org.eclipse.che.api.core.model.machine.MachineSource in project che by eclipse.
the class MachineSourceAdapterTest method testSerializeAndDeserialize.
/**
* Check we can transform object into JSON and JSON into object
*/
@Test
public void testSerializeAndDeserialize() {
MachineSourceAdapter machineSourceAdapter = spy(new MachineSourceAdapter());
Gson gson = new GsonBuilder().registerTypeAdapter(MachineSource.class, machineSourceAdapter).setPrettyPrinting().create();
final String TYPE = "myType";
final String LOCATION = "myLocation";
final String CONTENT = "myContent";
// serialize
MachineSource machineSource = new MachineSourceImpl(TYPE).setLocation(LOCATION).setContent(CONTENT);
String json = gson.toJson(machineSource, MachineSource.class);
assertNotNull(json);
// verify we called serializer
Mockito.verify(machineSourceAdapter).serialize(eq(machineSource), eq(MachineSource.class), any(JsonSerializationContext.class));
// now deserialize
MachineSource machineSourceDeserialize = gson.fromJson(new StringReader(json), MachineSource.class);
assertNotNull(machineSourceDeserialize);
assertEquals(machineSourceDeserialize.getLocation(), LOCATION);
assertEquals(machineSourceDeserialize.getType(), TYPE);
assertEquals(machineSourceDeserialize.getContent(), CONTENT);
// verify we called deserializer
Mockito.verify(machineSourceAdapter).deserialize(any(JsonElement.class), eq(MachineSource.class), any(JsonDeserializationContext.class));
}
use of org.eclipse.che.api.core.model.machine.MachineSource in project che by eclipse.
the class CheEnvironmentEngine method saveSnapshot.
/**
* Saves machine into snapshot.
*
* @param workspaceId
* ID of workspace that owns environment
* @param machineId
* ID of machine to save
* @return snapshot
* @throws EnvironmentNotRunningException
* if environment of machine is not running
* @throws NotFoundException
* if machine is not running
* @throws ServerException
* if another error occurs
*/
public SnapshotImpl saveSnapshot(String workspaceId, String machineId) throws ServerException, NotFoundException {
EnvironmentHolder environmentHolder;
SnapshotImpl snapshot = null;
Instance instance = null;
try (@SuppressWarnings("unused") Unlocker u = stripedLocks.readLock(workspaceId)) {
environmentHolder = environments.get(workspaceId);
if (environmentHolder == null || environmentHolder.status != EnvStatus.RUNNING) {
throw new EnvironmentNotRunningException(format("Environment '%s' is not running", workspaceId));
}
for (Instance machine : environmentHolder.machines) {
if (machine.getId().equals(machineId)) {
instance = machine;
snapshot = SnapshotImpl.builder().generateId().setType(machine.getConfig().getType()).setWorkspaceId(machine.getWorkspaceId()).setDescription(machine.getEnvName()).setDev(machine.getConfig().isDev()).setEnvName(machine.getEnvName()).setMachineName(machine.getConfig().getName()).useCurrentCreationDate().build();
}
}
}
if (instance == null) {
throw new NotFoundException(format("Machine with id '%s' is not found in environment of workspace '%s'", machineId, workspaceId));
}
try {
MachineSource machineSource = instance.saveToSnapshot();
snapshot.setMachineSource(new MachineSourceImpl(machineSource));
return snapshot;
} catch (ServerException e) {
try {
instance.getLogger().writeLine("Snapshot storing failed. " + e.getLocalizedMessage());
} catch (IOException ignore) {
}
throw e;
}
}
Aggregations