use of org.eclipse.che.api.environment.server.model.CheServiceImpl in project che by eclipse.
the class DefaultServicesStartStrategy method weightMachines.
/**
* Returns mapping of names of machines to its weights in dependency graph.
*
* @throws IllegalArgumentException
* if weights of machines can not be calculated
*/
private Map<String, Integer> weightMachines(Map<String, CheServiceImpl> services) throws IllegalArgumentException {
HashMap<String, Integer> weights = new HashMap<>();
// create machines dependency graph
Map<String, Set<String>> dependencies = new HashMap<>(services.size());
for (Map.Entry<String, CheServiceImpl> serviceEntry : services.entrySet()) {
CheServiceImpl service = serviceEntry.getValue();
Set<String> machineDependencies = Sets.newHashSetWithExpectedSize(service.getDependsOn().size() + service.getLinks().size() + service.getVolumesFrom().size());
for (String dependsOn : service.getDependsOn()) {
checkDependency(dependsOn, serviceEntry.getKey(), services, "A machine can not depend on itself");
machineDependencies.add(dependsOn);
}
// links also counts as dependencies
for (String link : service.getLinks()) {
String dependency = getServiceFromLink(link);
checkDependency(dependency, serviceEntry.getKey(), services, "A machine can not link to itself");
machineDependencies.add(dependency);
}
// volumesFrom also counts as dependencies
for (String volumesFrom : service.getVolumesFrom()) {
String dependency = getServiceFromVolumesFrom(volumesFrom);
checkDependency(dependency, serviceEntry.getKey(), services, "A machine can not contain 'volumes_from' to itself");
machineDependencies.add(dependency);
}
dependencies.put(serviceEntry.getKey(), machineDependencies);
}
// Nodes with no dependencies gets weight 0
while (!dependencies.isEmpty()) {
int previousSize = dependencies.size();
for (Iterator<Map.Entry<String, Set<String>>> it = dependencies.entrySet().iterator(); it.hasNext(); ) {
// process not yet processed machines only
Map.Entry<String, Set<String>> serviceEntry = it.next();
String service = serviceEntry.getKey();
Set<String> serviceDependencies = serviceEntry.getValue();
if (serviceDependencies.isEmpty()) {
// no links - smallest weight 0
weights.put(service, 0);
it.remove();
} else {
// machine has dependencies - check if it has not weighted dependencies
if (weights.keySet().containsAll(serviceDependencies)) {
// all connections are weighted - lets evaluate current machine
Optional<String> maxWeight = serviceDependencies.stream().max((o1, o2) -> weights.get(o1).compareTo(weights.get(o2)));
// optional can't be empty because size of the list is checked above
//noinspection OptionalGetWithoutIsPresent
weights.put(service, weights.get(maxWeight.get()) + 1);
it.remove();
}
}
}
if (dependencies.size() == previousSize) {
throw new IllegalArgumentException("Launch order of machines '" + Joiner.on(", ").join(dependencies.keySet()) + "' can't be evaluated. Circular dependency.");
}
}
return weights;
}
use of org.eclipse.che.api.environment.server.model.CheServiceImpl in project che by eclipse.
the class MachineProviderImplTest method shouldAddServersConfigsPortsFromMachineConfigToExposedPortsOnDevInstanceCreationFromRecipe.
@Test
public void shouldAddServersConfigsPortsFromMachineConfigToExposedPortsOnDevInstanceCreationFromRecipe() throws Exception {
// given
final boolean isDev = true;
CheServiceImpl machine = createService();
machine.setExpose(asList("9090", "8080"));
// when
createInstanceFromRecipe(machine, isDev);
// then
ArgumentCaptor<CreateContainerParams> argumentCaptor = ArgumentCaptor.forClass(CreateContainerParams.class);
verify(dockerConnector).createContainer(argumentCaptor.capture());
assertTrue(new ArrayList<>(argumentCaptor.getValue().getContainerConfig().getExposedPorts().keySet()).containsAll(asList("9090", "8080")));
}
use of org.eclipse.che.api.environment.server.model.CheServiceImpl in project che by eclipse.
the class MachineProviderImplTest method shouldAddAllVolumesOnDevInstanceCreationFromRecipe.
@Test
public void shouldAddAllVolumesOnDevInstanceCreationFromRecipe() throws Exception {
String[] bindMountVolumesFromMachine = new String[] { "/my/bind/mount1:/from/host1", "/my/bind/mount2:/from/host2:ro", "/my/bind/mount3:/from/host3:ro,Z" };
String[] volumesFromMachine = new String[] { "/projects", "/something", "/something/else" };
String[] allMachinesSystemVolumes = new String[] { "/some/thing/else:/home/some/thing/else", "/other/path:/home/other/path", "/home/other/path2" };
String[] devMachinesSystemVolumes = new String[] { "/etc:/tmp/etc:ro", "/some/thing:/home/some/thing", "/some/thing2:/home/some/thing2:ro,z", "/home/some/thing3" };
String[] expectedBindMountVolumes = new String[] { "/my/bind/mount1:/from/host1", "/my/bind/mount2:/from/host2:ro", "/my/bind/mount3:/from/host3:ro,Z", "/some/thing/else:/home/some/thing/else", "/other/path:/home/other/path", "/etc:/tmp/etc:ro", "/some/thing:/home/some/thing", "/some/thing2:/home/some/thing2:ro,z" };
Map<String, Volume> expectedVolumes = Stream.of("/projects", "/something", "/something/else", "/home/other/path2", "/home/some/thing3").collect(toMap(Function.identity(), v -> new Volume()));
provider = new MachineProviderBuilder().setDevMachineVolumes(new HashSet<>(asList(devMachinesSystemVolumes))).setAllMachineVolumes(new HashSet<>(asList(allMachinesSystemVolumes))).build();
CheServiceImpl service = createService();
service.setVolumes(Stream.concat(Stream.of(bindMountVolumesFromMachine), Stream.of(volumesFromMachine)).collect(Collectors.toList()));
createInstanceFromRecipe(service, true);
ArgumentCaptor<CreateContainerParams> argumentCaptor = ArgumentCaptor.forClass(CreateContainerParams.class);
verify(dockerConnector).createContainer(argumentCaptor.capture());
String[] actualBindMountVolumes = argumentCaptor.getValue().getContainerConfig().getHostConfig().getBinds();
Map<String, Volume> actualVolumes = argumentCaptor.getValue().getContainerConfig().getVolumes();
assertEquals(actualVolumes, expectedVolumes);
assertEqualsNoOrder(actualBindMountVolumes, expectedBindMountVolumes);
}
use of org.eclipse.che.api.environment.server.model.CheServiceImpl in project che by eclipse.
the class MachineProviderImplTest method shouldAddCommonsSystemVolumesOnlyOnNonDevInstanceCreationFromRecipe.
@Test
public void shouldAddCommonsSystemVolumesOnlyOnNonDevInstanceCreationFromRecipe() throws Exception {
String[] bindMountVolumesFromMachine = new String[] { "/my/bind/mount1:/from/host1", "/my/bind/mount2:/from/host2:ro", "/my/bind/mount3:/from/host3:ro,Z" };
String[] volumesFromMachine = new String[] { "/projects", "/something", "/something/else" };
String[] allMachinesSystemVolumes = new String[] { "/some/thing/else:/home/some/thing/else", "/other/path:/home/other/path", "/home/other/path2" };
String[] devMachinesSystemVolumes = new String[] { "/etc:/tmp/etc:ro", "/some/thing:/home/some/thing", "/some/thing2:/home/some/thing2:ro,z", "/home/some/thing3" };
String[] expectedBindMountVolumes = new String[] { "/my/bind/mount1:/from/host1", "/my/bind/mount2:/from/host2:ro", "/my/bind/mount3:/from/host3:ro,Z", "/some/thing/else:/home/some/thing/else", "/other/path:/home/other/path" };
Map<String, Volume> expectedVolumes = Stream.of("/projects", "/something", "/something/else", "/home/other/path2").collect(toMap(Function.identity(), v -> new Volume()));
provider = new MachineProviderBuilder().setDevMachineVolumes(new HashSet<>(asList(devMachinesSystemVolumes))).setAllMachineVolumes(new HashSet<>(asList(allMachinesSystemVolumes))).build();
CheServiceImpl service = createService();
service.setVolumes(Stream.concat(Stream.of(bindMountVolumesFromMachine), Stream.of(volumesFromMachine)).collect(Collectors.toList()));
createInstanceFromRecipe(service, false);
ArgumentCaptor<CreateContainerParams> argumentCaptor = ArgumentCaptor.forClass(CreateContainerParams.class);
verify(dockerConnector).createContainer(argumentCaptor.capture());
String[] actualBindMountVolumes = argumentCaptor.getValue().getContainerConfig().getHostConfig().getBinds();
Map<String, Volume> actualVolumes = argumentCaptor.getValue().getContainerConfig().getVolumes();
assertEquals(actualVolumes, expectedVolumes);
assertEqualsNoOrder(actualBindMountVolumes, expectedBindMountVolumes);
}
use of org.eclipse.che.api.environment.server.model.CheServiceImpl in project che by eclipse.
the class MachineProviderImplTest method shouldAddBindMountAndRegularVolumesOnInstanceCreationFromRecipe.
@Test
public void shouldAddBindMountAndRegularVolumesOnInstanceCreationFromRecipe() throws Exception {
String[] bindMountVolumesFromMachine = new String[] { "/my/bind/mount1:/from/host1", "/my/bind/mount2:/from/host2:ro", "/my/bind/mount3:/from/host3:ro,Z" };
String[] volumesFromMachine = new String[] { "/projects", "/something", "/something/else" };
String[] expectedBindMountVolumes = new String[] { "/my/bind/mount1:/from/host1", "/my/bind/mount2:/from/host2:ro", "/my/bind/mount3:/from/host3:ro,Z" };
Map<String, Volume> expectedVolumes = Stream.of("/projects", "/something", "/something/else").collect(toMap(Function.identity(), v -> new Volume()));
provider = new MachineProviderBuilder().setDevMachineVolumes(emptySet()).setAllMachineVolumes(emptySet()).build();
CheServiceImpl service = createService();
service.setVolumes(Stream.concat(Stream.of(bindMountVolumesFromMachine), Stream.of(volumesFromMachine)).collect(Collectors.toList()));
createInstanceFromRecipe(service, true);
ArgumentCaptor<CreateContainerParams> argumentCaptor = ArgumentCaptor.forClass(CreateContainerParams.class);
verify(dockerConnector).createContainer(argumentCaptor.capture());
String[] actualBindMountVolumes = argumentCaptor.getValue().getContainerConfig().getHostConfig().getBinds();
Map<String, Volume> actualVolumes = argumentCaptor.getValue().getContainerConfig().getVolumes();
assertEquals(actualVolumes, expectedVolumes);
assertEqualsNoOrder(actualBindMountVolumes, expectedBindMountVolumes);
}
Aggregations