Adapt docker infra code to changes related to InternalEnvironments

6.19.x
Sergii Leshchenko 2017-11-16 11:47:27 +02:00
parent a74466308d
commit 6986efc6a3
33 changed files with 394 additions and 618 deletions

View File

@ -16,19 +16,6 @@ import org.eclipse.che.api.core.ValidationException;
/** @author Alexander Garagatyi */
public class ArgumentsValidator {
/**
* Checks that object reference is not null, throws {@link ValidationException} otherwise.
*
* <p>Exception uses error message built from error message template and error message parameters.
*/
public static void checkNotNull(
Object object, String errorMessageTemplate, Object... errorMessageParams)
throws ValidationException {
if (object == null) {
throw new ValidationException(format(errorMessageTemplate, errorMessageParams));
}
}
public static void checkArgument(boolean expression, String error) throws ValidationException {
if (!expression) {
throw new ValidationException(error);

View File

@ -12,7 +12,6 @@ package org.eclipse.che.workspace.infrastructure.docker;
import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity;
import org.eclipse.che.api.workspace.server.spi.InfrastructureException;
import org.eclipse.che.api.workspace.server.spi.environment.InternalEnvironment;
import org.eclipse.che.workspace.infrastructure.docker.model.DockerEnvironment;
/**
@ -20,16 +19,14 @@ import org.eclipse.che.workspace.infrastructure.docker.model.DockerEnvironment;
*
* @author Alexander Garagatyi
*/
public interface InfrastructureProvisioner {
public interface DockerEnvironmentProvisioner {
/**
* Modifies environment config and internal environment representation with everything needed for
* infrastructure of workspace.
*
* @param environment configuration of environment
* @param internalEnv internal environment representation
* @throws InfrastructureException if any error occurs
*/
void provision(
InternalEnvironment environment, DockerEnvironment internalEnv, RuntimeIdentity identity)
void provision(DockerEnvironment internalEnv, RuntimeIdentity identity)
throws InfrastructureException;
}

View File

@ -18,7 +18,8 @@ import org.eclipse.che.api.workspace.server.spi.provision.env.CheApiEnvVarProvid
import org.eclipse.che.infrastructure.docker.client.DockerRegistryDynamicAuthResolver;
import org.eclipse.che.infrastructure.docker.client.NoOpDockerRegistryDynamicAuthResolverImpl;
import org.eclipse.che.workspace.infrastructure.docker.bootstrap.DockerBootstrapperFactory;
import org.eclipse.che.workspace.infrastructure.docker.environment.DockerEnvironmentTypeModule;
import org.eclipse.che.workspace.infrastructure.docker.environment.DockerEnvironmentsModule;
import org.eclipse.che.workspace.infrastructure.docker.environment.convert.DockerEnvironmentConvertersModule;
import org.eclipse.che.workspace.infrastructure.docker.provisioner.ContainerSystemSettingsProvisioner;
import org.eclipse.che.workspace.infrastructure.docker.provisioner.ContainerSystemSettingsProvisioningModule;
import org.eclipse.che.workspace.infrastructure.docker.provisioner.cgroup.CGroupParentProvisioner;
@ -51,7 +52,8 @@ public class DockerInfraModule extends AbstractModule {
settingsProvisioners.addBinding().to(CpuLimitsProvisioner.class);
settingsProvisioners.addBinding().to(PrivilegedModeProvisioner.class);
install(new DockerEnvironmentTypeModule());
install(new DockerEnvironmentsModule());
install(new DockerEnvironmentConvertersModule());
install(new ContainerSystemSettingsProvisioningModule());
bind(CheApiEnvVarProvider.class).to(DockerCheApiEnvVarProvider.class);

View File

@ -34,9 +34,9 @@ import org.eclipse.che.api.workspace.server.hc.ServersCheckerFactory;
import org.eclipse.che.api.workspace.server.model.impl.MachineImpl;
import org.eclipse.che.api.workspace.server.spi.InfrastructureException;
import org.eclipse.che.api.workspace.server.spi.InternalInfrastructureException;
import org.eclipse.che.api.workspace.server.spi.environment.InternalMachineConfig;
import org.eclipse.che.api.workspace.server.spi.InternalRuntime;
import org.eclipse.che.api.workspace.server.spi.RuntimeStartInterruptedException;
import org.eclipse.che.api.workspace.server.spi.environment.InternalMachineConfig;
import org.eclipse.che.api.workspace.shared.dto.event.MachineStatusEvent;
import org.eclipse.che.api.workspace.shared.dto.event.RuntimeStatusEvent;
import org.eclipse.che.api.workspace.shared.dto.event.ServerStatusEvent;
@ -154,14 +154,14 @@ public class DockerInternalRuntime extends InternalRuntime<DockerRuntimeContext>
@Override
protected void internalStart(Map<String, String> startOptions) throws InfrastructureException {
startSynchronizer.setStartThread();
Map<String, DockerContainerConfig> machineName2config =
getContext().getDockerEnvironment().getContainers();
try {
networks.createNetwork(getContext().getDockerEnvironment().getNetwork());
networks.createNetwork(getContext().getEnvironment().getNetwork());
for (String machineName : getContext().getOrderedContainers()) {
for (Map.Entry<String, DockerContainerConfig> containerEntry :
getContext().getEnvironment().getContainers().entrySet()) {
checkInterruption();
final DockerContainerConfig config = machineName2config.get(machineName);
String machineName = containerEntry.getKey();
final DockerContainerConfig config = containerEntry.getValue();
sendStartingEvent(machineName);
try {
startMachine(machineName, config);
@ -247,7 +247,7 @@ public class DockerInternalRuntime extends InternalRuntime<DockerRuntimeContext>
DockerMachine machine =
containerStarter.startContainer(
getContext().getDockerEnvironment().getNetwork(),
getContext().getEnvironment().getNetwork(),
name,
containerConfig,
getContext().getIdentity(),
@ -260,7 +260,7 @@ public class DockerInternalRuntime extends InternalRuntime<DockerRuntimeContext>
destroyMachineQuietly(name, machine);
throw e;
}
if (!machineCfg.getInstallers().isEmpty()) {
if (machineCfg != null && !machineCfg.getInstallers().isEmpty()) {
bootstrapperFactory
.create(name, getContext().getIdentity(), machineCfg.getInstallers(), machine)
.bootstrap();
@ -321,7 +321,7 @@ public class DockerInternalRuntime extends InternalRuntime<DockerRuntimeContext>
sendStoppedEvent(entry.getKey());
}
// TODO what happens when context throws exception here
networks.destroyNetwork(getContext().getDockerEnvironment().getNetwork());
networks.destroyNetwork(getContext().getEnvironment().getNetwork());
}
/** Destroys specified machine with suppressing exception that occurs while destroying. */

View File

@ -112,7 +112,7 @@ import org.slf4j.Logger;
}
2. Move the logic related to containers configuration modification to
InfrastructureProvisioner implementation.
DockerEnvironmentProvisioner implementation.
*/
/**

View File

@ -10,7 +10,6 @@
*/
package org.eclipse.che.workspace.infrastructure.docker;
import com.google.common.collect.ImmutableList;
import com.google.inject.assistedinject.Assisted;
import com.google.inject.assistedinject.AssistedInject;
import java.net.URI;
@ -20,7 +19,6 @@ import javax.inject.Named;
import org.eclipse.che.api.core.ValidationException;
import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity;
import org.eclipse.che.api.workspace.server.spi.InfrastructureException;
import org.eclipse.che.api.workspace.server.spi.environment.InternalEnvironment;
import org.eclipse.che.api.workspace.server.spi.InternalInfrastructureException;
import org.eclipse.che.api.workspace.server.spi.RuntimeContext;
import org.eclipse.che.infrastructure.docker.client.json.ContainerListEntry;
@ -36,12 +34,10 @@ import org.slf4j.LoggerFactory;
* @author Alexander Garagatyi
* @author Yevhenii Voievodin
*/
public class DockerRuntimeContext extends RuntimeContext {
public class DockerRuntimeContext extends RuntimeContext<DockerEnvironment> {
private static final Logger LOG = LoggerFactory.getLogger(DockerRuntimeContext.class);
private final DockerEnvironment dockerEnvironment;
private final List<String> orderedContainers;
private final ExternalIpURLRewriter urlRewriter;
private final String websocketOutputEndpoint;
private final DockerRuntimeFactory runtimeFactory;
@ -53,9 +49,7 @@ public class DockerRuntimeContext extends RuntimeContext {
public DockerRuntimeContext(
@Assisted DockerRuntimeInfrastructure infrastructure,
@Assisted RuntimeIdentity identity,
@Assisted InternalEnvironment environment,
@Assisted DockerEnvironment dockerEnv,
@Assisted List<String> containersOrder,
DockerRuntimeFactory runtimeFactory,
DockerContainers containers,
DockerSharedPool sharedPool,
@ -64,9 +58,7 @@ public class DockerRuntimeContext extends RuntimeContext {
@Named("che.websocket.endpoint") String cheWebsocketEndpoint)
throws InfrastructureException, ValidationException {
super(environment, identity, infrastructure);
this.dockerEnvironment = dockerEnv;
this.orderedContainers = ImmutableList.copyOf(containersOrder);
super(dockerEnv, identity, infrastructure);
this.urlRewriter = urlRewriter;
this.websocketOutputEndpoint = cheWebsocketEndpoint;
this.runtimeFactory = runtimeFactory;
@ -75,16 +67,6 @@ public class DockerRuntimeContext extends RuntimeContext {
this.consistencyChecker = consistencyChecker;
}
/** Returns docker environment which based on normalized context environment configuration. */
public DockerEnvironment getDockerEnvironment() {
return dockerEnvironment;
}
/** Returns the list of the ordered containers, machines must be started in the same order. */
public List<String> getOrderedContainers() {
return orderedContainers;
}
@Override
public URI getOutputChannel() throws InfrastructureException {
try {

View File

@ -10,20 +10,15 @@
*/
package org.eclipse.che.workspace.infrastructure.docker;
import java.util.List;
import org.eclipse.che.api.core.ValidationException;
import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity;
import org.eclipse.che.api.workspace.server.spi.InfrastructureException;
import org.eclipse.che.api.workspace.server.spi.environment.InternalEnvironment;
import org.eclipse.che.workspace.infrastructure.docker.model.DockerEnvironment;
/** Helps to create {@link DockerRuntimeContext} instances. */
public interface DockerRuntimeContextFactory {
DockerRuntimeContext create(
DockerRuntimeInfrastructure infra,
RuntimeIdentity identity,
InternalEnvironment environment,
DockerEnvironment dockerEnv,
List<String> containersOrder)
DockerRuntimeInfrastructure infra, RuntimeIdentity identity, DockerEnvironment dockerEnv)
throws InfrastructureException, ValidationException;
}

View File

@ -10,23 +10,23 @@
*/
package org.eclipse.che.workspace.infrastructure.docker;
import static java.lang.String.format;
import com.google.common.base.Joiner;
import com.google.inject.Inject;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.che.api.core.ValidationException;
import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity;
import org.eclipse.che.api.core.notification.EventService;
import org.eclipse.che.api.workspace.server.spi.InfrastructureException;
import org.eclipse.che.api.workspace.server.spi.environment.InternalEnvironment;
import org.eclipse.che.api.workspace.server.spi.RuntimeContext;
import org.eclipse.che.api.workspace.server.spi.RuntimeInfrastructure;
import org.eclipse.che.workspace.infrastructure.docker.container.ContainersStartStrategy;
import org.eclipse.che.api.workspace.server.spi.environment.InternalEnvironment;
import org.eclipse.che.api.workspace.server.spi.provision.InternalEnvironmentProvisioner;
import org.eclipse.che.workspace.infrastructure.docker.container.DockerContainers;
import org.eclipse.che.workspace.infrastructure.docker.environment.DockerConfigSourceSpecificEnvironmentParser;
import org.eclipse.che.workspace.infrastructure.docker.environment.EnvironmentNormalizer;
import org.eclipse.che.workspace.infrastructure.docker.environment.compose.ComposeInternalEnvironment;
import org.eclipse.che.workspace.infrastructure.docker.environment.dockerfile.DockerfileInternalEnvironment;
import org.eclipse.che.workspace.infrastructure.docker.environment.dockerimage.DockerimageInternalEnvironment;
import org.eclipse.che.workspace.infrastructure.docker.environment.DockerEnvironmentNormalizer;
import org.eclipse.che.workspace.infrastructure.docker.environment.convert.DockerEnvironmentConverter;
import org.eclipse.che.workspace.infrastructure.docker.model.DockerEnvironment;
/**
@ -37,65 +37,62 @@ import org.eclipse.che.workspace.infrastructure.docker.model.DockerEnvironment;
*/
public class DockerRuntimeInfrastructure extends RuntimeInfrastructure {
private final ContainersStartStrategy startStrategy;
private final InfrastructureProvisioner infrastructureProvisioner;
private final EnvironmentNormalizer environmentNormalizer;
public static String NAME = "docker";
private final Map<String, DockerEnvironmentConverter> envConverters;
private final DockerEnvironmentProvisioner dockerEnvProvisioner;
private final DockerEnvironmentNormalizer dockerEnvNormalizer;
private final DockerRuntimeContextFactory contextFactory;
private final DockerContainers containers;
@Inject
public DockerRuntimeInfrastructure(
ContainersStartStrategy startStrategy,
InfrastructureProvisioner infrastructureProvisioner,
EnvironmentNormalizer environmentNormalizer,
Map<String, DockerConfigSourceSpecificEnvironmentParser> environmentParsers,
EventService eventService,
Map<String, DockerEnvironmentConverter> envConverters,
DockerEnvironmentProvisioner dockerEnvProvisioner,
DockerEnvironmentNormalizer dockerEnvNormalizer,
DockerRuntimeContextFactory contextFactory,
DockerContainers containers,
EventService eventService) {
super("docker", environmentParsers.keySet(), eventService);
this.startStrategy = startStrategy;
this.infrastructureProvisioner = infrastructureProvisioner;
this.environmentNormalizer = environmentNormalizer;
Set<InternalEnvironmentProvisioner> internalEnvironmentProvisioners) {
super(NAME, envConverters.keySet(), eventService, internalEnvironmentProvisioners);
this.envConverters = envConverters;
this.dockerEnvProvisioner = dockerEnvProvisioner;
this.dockerEnvNormalizer = dockerEnvNormalizer;
this.contextFactory = contextFactory;
this.containers = containers;
}
@Override
public DockerRuntimeContext prepare(RuntimeIdentity identity, InternalEnvironment environment)
protected RuntimeContext internalPrepare(
RuntimeIdentity identity, InternalEnvironment environment)
throws ValidationException, InfrastructureException {
DockerEnvironment dockerEnvironment;
String type = environment.getRecipe().getType();
switch (type) {
case "dockerfile":
dockerEnvironment = ((DockerfileInternalEnvironment) environment).getDockerEnvironment();
break;
case "dockerimage":
dockerEnvironment = ((DockerimageInternalEnvironment) environment).getDockerEnvironment();
break;
case "compose":
dockerEnvironment = ((ComposeInternalEnvironment) environment).getComposeEnvironment();
break;
default:
throw new InfrastructureException("Recipe type is not allowed " + type);
}
DockerEnvironment dockerEnvironment = convertToDockerEnv(environment);
// modify environment with everything needed to use docker machines on particular (cloud)
// infrastructure
infrastructureProvisioner.provision(environment, dockerEnvironment, identity);
// check that containers start order can be resolved
// NOTE: it should be performed before environmentNormalizer.normalize because normalization
// changes links, volumes from which will fail order evaluation
// It can be changed after reimplementing strategy to respect normalization
List<String> containersOrder = startStrategy.order(dockerEnvironment);
// normalize env to provide environment description with absolutely everything expected in
environmentNormalizer.normalize(environment, dockerEnvironment, identity);
dockerEnvProvisioner.provision(dockerEnvironment, identity);
return contextFactory.create(this, identity, environment, dockerEnvironment, containersOrder);
// normalize env to provide environment description with absolutely everything expected in
dockerEnvNormalizer.normalize(dockerEnvironment, identity);
return contextFactory.create(this, identity, dockerEnvironment);
}
@Override
public Set<RuntimeIdentity> getIdentities() throws InfrastructureException {
return containers.findIdentities();
}
private DockerEnvironment convertToDockerEnv(InternalEnvironment sourceEnv)
throws ValidationException {
String recipeType = sourceEnv.getRecipe().getType();
DockerEnvironmentConverter converter = envConverters.get(recipeType);
if (converter == null) {
throw new ValidationException(
format(
"Environment type '%s' is not supported. Supported environment types: %s",
recipeType, Joiner.on(", ").join(envConverters.keySet())));
}
return converter.convert(sourceEnv);
}
}

View File

@ -1,39 +0,0 @@
/*
* Copyright (c) 2012-2017 Red Hat, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.workspace.infrastructure.docker.environment;
import org.eclipse.che.api.core.ValidationException;
import org.eclipse.che.api.core.model.workspace.config.Environment;
import org.eclipse.che.api.core.model.workspace.config.Recipe;
import org.eclipse.che.api.workspace.server.spi.InfrastructureException;
import org.eclipse.che.api.workspace.server.spi.environment.InternalEnvironment;
import org.eclipse.che.workspace.infrastructure.docker.model.DockerEnvironment;
/**
* Parser for creating {@link DockerEnvironment} with parameters defined in the {@link Environment}.
*
* @author Alexander Andrienko
*/
public interface DockerConfigSourceSpecificEnvironmentParser {
/**
* Parses compose file from {@link Environment} into {@link DockerEnvironment}.
*
* <p>{@link Recipe#getContent()} in {@code Environment} must not be null even. It is supposed
* that class that uses this methods sets it if needed.
*
* @param environment environment to parsing
* @throws ValidationException in case invalid argument in the {@link Environment}
* @throws InfrastructureException when parsing fails due to some internal server error or
* inability to parse environment due to other reasons
*/
DockerEnvironment parse(InternalEnvironment environment)
throws ValidationException, InfrastructureException;
}

View File

@ -18,24 +18,20 @@ import java.util.Map;
import javax.inject.Inject;
import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity;
import org.eclipse.che.api.workspace.server.spi.InfrastructureException;
import org.eclipse.che.api.workspace.server.spi.environment.InternalEnvironment;
import org.eclipse.che.workspace.infrastructure.docker.container.ContainerNameGenerator;
import org.eclipse.che.workspace.infrastructure.docker.model.DockerContainerConfig;
import org.eclipse.che.workspace.infrastructure.docker.model.DockerEnvironment;
/** @author Alexander Garagatyi */
public class EnvironmentNormalizer {
public class DockerEnvironmentNormalizer {
private final ContainerNameGenerator containerNameGenerator;
@Inject
public EnvironmentNormalizer(ContainerNameGenerator containerNameGenerator) {
public DockerEnvironmentNormalizer(ContainerNameGenerator containerNameGenerator) {
this.containerNameGenerator = containerNameGenerator;
}
public void normalize(
InternalEnvironment environment,
DockerEnvironment dockerEnvironment,
RuntimeIdentity identity)
public void normalize(DockerEnvironment dockerEnvironment, RuntimeIdentity identity)
throws InfrastructureException {
String networkId = identity.getWorkspaceId() + "_" + identity.getEnvName();

View File

@ -1,31 +0,0 @@
/*
* Copyright (c) 2012-2017 Red Hat, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.workspace.infrastructure.docker.environment;
import com.google.inject.AbstractModule;
import com.google.inject.multibindings.MapBinder;
import org.eclipse.che.api.workspace.server.spi.environment.InternalEnvironmentFactory;
import org.eclipse.che.workspace.infrastructure.docker.environment.compose.ComposeInternalEnvironmentFactory;
import org.eclipse.che.workspace.infrastructure.docker.environment.dockerfile.DockerfileInternalEnvironmentFactory;
import org.eclipse.che.workspace.infrastructure.docker.environment.dockerimage.DockerimageInternalEnvironmentFactory;
/** @author Alexander Garagatyi */
public class DockerEnvironmentTypeModule extends AbstractModule {
@Override
protected void configure() {
// Environment type
MapBinder<String, InternalEnvironmentFactory> environmentFactories =
MapBinder.newMapBinder(binder(), String.class, InternalEnvironmentFactory.class);
environmentFactories.addBinding(ComposeInternalEnvironmentFactory.TYPE).to(ComposeInternalEnvironmentFactory.class);
environmentFactories.addBinding(DockerfileInternalEnvironmentFactory.TYPE).to(DockerfileInternalEnvironmentFactory.class);
environmentFactories.addBinding(DockerimageInternalEnvironmentFactory.TYPE).to(DockerimageInternalEnvironmentFactory.class);
}
}

View File

@ -1,91 +0,0 @@
/*
* Copyright (c) 2012-2017 Red Hat, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.workspace.infrastructure.docker.environment;
import static java.lang.String.format;
import static java.util.stream.Collectors.toList;
import static org.eclipse.che.workspace.infrastructure.docker.ArgumentsValidator.checkNotNull;
import com.google.common.base.Joiner;
import java.util.Map;
import javax.inject.Inject;
import org.eclipse.che.api.core.ValidationException;
import org.eclipse.che.api.core.model.workspace.config.Environment;
import org.eclipse.che.api.workspace.server.spi.InfrastructureException;
import org.eclipse.che.api.workspace.server.spi.environment.InternalEnvironment;
import org.eclipse.che.api.workspace.server.spi.environment.InternalMachineConfig;
import org.eclipse.che.api.workspace.server.spi.environment.InternalRecipe;
import org.eclipse.che.workspace.infrastructure.docker.model.DockerContainerConfig;
import org.eclipse.che.workspace.infrastructure.docker.model.DockerEnvironment;
/**
* Parses {@link Environment} into {@link DockerEnvironment}.
*
* @author Alexander Garagatyi
* @author Alexander Andrienko
*/
public class EnvironmentParser {
private final Map<String, DockerConfigSourceSpecificEnvironmentParser> environmentParsers;
@Inject
public EnvironmentParser(
Map<String, DockerConfigSourceSpecificEnvironmentParser> environmentParsers) {
this.environmentParsers = environmentParsers;
}
/**
* Parses {@link Environment} into {@link DockerEnvironment}.
*
* @param environment environment to parse
* @return environment representation as compose environment
* @throws ValidationException if provided environment is illegal
* @throws InfrastructureException if fetching of environment recipe content fails
*/
public DockerEnvironment parse(InternalEnvironment environment)
throws ValidationException, InfrastructureException {
checkNotNull(environment, "Environment should not be null");
InternalRecipe recipe = environment.getRecipe();
checkNotNull(recipe, "Environment recipe should not be null");
checkNotNull(recipe.getType(), "Environment recipe type should not be null");
checkNotNull(recipe.getContent(), "Recipe of environment must contain content");
DockerConfigSourceSpecificEnvironmentParser parser = environmentParsers.get(recipe.getType());
if (parser == null) {
throw new ValidationException(
format(
"Environment type '%s' is not supported. " + "Supported environment types: %s",
recipe.getType(), Joiner.on(", ").join(environmentParsers.keySet())));
}
DockerEnvironment dockerEnvironment = parser.parse(environment);
for (Map.Entry<String, DockerContainerConfig> entry :
dockerEnvironment.getContainers().entrySet()) {
InternalMachineConfig machineConfig = environment.getMachines().get(entry.getKey());
if (machineConfig != null) {
entry
.getValue()
.setExpose(
entry
.getValue()
.getExpose()
.stream()
.map(expose -> expose.contains("/") ? expose : expose + "/tcp")
.distinct()
.collect(toList()));
}
}
return dockerEnvironment;
}
}

View File

@ -1,256 +0,0 @@
/*
* Copyright (c) 2012-2017 Red Hat, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.workspace.infrastructure.docker.environment;
import static com.google.common.base.Strings.isNullOrEmpty;
import static java.util.stream.Collectors.toList;
import static org.eclipse.che.workspace.infrastructure.docker.ArgumentsValidator.checkArgument;
import com.google.common.base.Joiner;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.che.api.core.ValidationException;
import org.eclipse.che.api.core.model.workspace.config.ServerConfig;
import org.eclipse.che.api.workspace.server.WsAgentMachineFinderUtil;
import org.eclipse.che.api.workspace.server.spi.InfrastructureException;
import org.eclipse.che.api.workspace.server.spi.environment.InternalMachineConfig;
import org.eclipse.che.commons.annotation.Nullable;
import org.eclipse.che.workspace.infrastructure.docker.model.DockerContainerConfig;
import org.eclipse.che.workspace.infrastructure.docker.model.DockerEnvironment;
/** @author Alexander Garagatyi */
public class EnvironmentValidator {
/* machine name must contain only {a-zA-Z0-9_-} characters and it's needed for validation machine names */
private static final String MACHINE_NAME_REGEXP = "[a-zA-Z0-9]+[a-zA-Z0-9_-]*";
private static final Pattern MACHINE_NAME_PATTERN =
Pattern.compile("^" + MACHINE_NAME_REGEXP + "$");
private static final Pattern SERVER_PORT = Pattern.compile("^[1-9]+[0-9]*(/(tcp|udp))?$");
private static final Pattern SERVER_PROTOCOL = Pattern.compile("^[a-z][a-z0-9-+.]*$");
// DockerContainer syntax patterns
/**
* Examples:
*
* <ul>
* <li>8080/tcp
* <li>8080/udp
* <li>8080
* <li>8/tcp
* <li>8
* </ul>
*/
private static final Pattern EXPOSE_PATTERN = Pattern.compile("^[1-9]+[0-9]*(/(tcp|udp))?$");
/**
* Examples:
*
* <ul>
* <li>service1
* <li>service1:alias1
* </ul>
*/
private static final Pattern LINK_PATTERN =
Pattern.compile(
"^(?<containerName>" + MACHINE_NAME_REGEXP + ")(:" + MACHINE_NAME_REGEXP + ")?$");
private static final Pattern VOLUME_FROM_PATTERN =
Pattern.compile("^(?<containerName>" + MACHINE_NAME_REGEXP + ")(:(ro|rw))?$");
public void validate(
Map<String, InternalMachineConfig> machines, DockerEnvironment dockerEnvironment)
throws ValidationException, InfrastructureException {
checkArgument(
dockerEnvironment.getContainers() != null && !dockerEnvironment.getContainers().isEmpty(),
"Environment should contain at least 1 container");
checkArgument(
machines != null && !machines.isEmpty(), "Environment should contain at least 1 machine");
List<String> missingContainers =
machines
.keySet()
.stream()
.filter(machineName -> !dockerEnvironment.getContainers().containsKey(machineName))
.collect(toList());
checkArgument(
missingContainers.isEmpty(),
"Environment contains machines that are missing in environment recipe: %s",
Joiner.on(", ").join(missingContainers));
List<String> machinesWithWsagentServer =
machines
.entrySet()
.stream()
.filter(
entry ->
WsAgentMachineFinderUtil.containsWsAgentServerOrInstaller(entry.getValue()))
.map(Map.Entry::getKey)
.collect(toList());
checkArgument(
machinesWithWsagentServer.size() == 1,
"Environment should contain exactly 1 machine with wsagent, but contains '%s'. "
+ "All machines with this agent: %s",
machinesWithWsagentServer.size(),
Joiner.on(", ").join(machinesWithWsagentServer));
// needed to validate different kinds of dependencies in containers to other containers
Set<String> containersNames = dockerEnvironment.getContainers().keySet();
for (Map.Entry<String, DockerContainerConfig> entry :
dockerEnvironment.getContainers().entrySet()) {
validateMachine(
entry.getKey(), machines.get(entry.getKey()), entry.getValue(), containersNames);
}
}
private void validateMachine(
String machineName,
@Nullable InternalMachineConfig machineConfig,
DockerContainerConfig container,
Set<String> containersNames)
throws ValidationException {
checkArgument(
MACHINE_NAME_PATTERN.matcher(machineName).matches(),
"Name of machine '%s' in environment is invalid",
machineName);
checkArgument(
!isNullOrEmpty(container.getImage())
|| (container.getBuild() != null
&& (!isNullOrEmpty(container.getBuild().getContext())
|| !isNullOrEmpty(container.getBuild().getDockerfileContent()))),
"Field 'image' or 'build.context' is required in machine '%s' in environment",
machineName);
checkArgument(
container.getBuild() == null
|| (isNullOrEmpty(container.getBuild().getContext())
!= isNullOrEmpty(container.getBuild().getDockerfileContent())),
"Machine '%s' in environment contains mutually exclusive dockerfile content and build context.",
machineName);
if (machineConfig != null) {
validateExtendedMachine(machineConfig, machineName);
}
for (String expose : container.getExpose()) {
checkArgument(
EXPOSE_PATTERN.matcher(expose).matches(),
"Exposed port '%s' in machine '%s' in environment is invalid",
expose,
machineName);
}
for (String link : container.getLinks()) {
Matcher matcher = LINK_PATTERN.matcher(link);
checkArgument(
matcher.matches(),
"Link '%s' in machine '%s' in environment is invalid",
link,
machineName);
String containerFromLink = matcher.group("containerName");
checkArgument(
!machineName.equals(containerFromLink),
"Container '%s' has illegal link to itself",
machineName);
checkArgument(
containersNames.contains(containerFromLink),
"Machine '%s' in environment contains link to non existing machine '%s'",
machineName,
containerFromLink);
}
for (String depends : container.getDependsOn()) {
checkArgument(
MACHINE_NAME_PATTERN.matcher(depends).matches(),
"Dependency '%s' in machine '%s' in environment is invalid",
depends,
machineName);
checkArgument(
!machineName.equals(depends),
"Container '%s' has illegal dependency to itself",
machineName);
checkArgument(
containersNames.contains(depends),
"Machine '%s' in environment contains dependency to non existing machine '%s'",
machineName,
depends);
}
for (String volumesFrom : container.getVolumesFrom()) {
Matcher matcher = VOLUME_FROM_PATTERN.matcher(volumesFrom);
checkArgument(
matcher.matches(),
"Machine name '%s' in field 'volumes_from' of machine '%s' in environment is invalid",
volumesFrom,
machineName);
String containerFromVolumesFrom = matcher.group("containerName");
checkArgument(
!machineName.equals(containerFromVolumesFrom),
"Container '%s' can not mount volume from itself",
machineName);
checkArgument(
containersNames.contains(containerFromVolumesFrom),
"Machine '%s' in environment contains non existing machine '%s' in 'volumes_from' field",
machineName,
containerFromVolumesFrom);
}
checkArgument(
container.getPorts() == null || container.getPorts().isEmpty(),
"Ports binding is forbidden but found in machine '%s' of environment",
machineName);
checkArgument(
container.getVolumes() == null || container.getVolumes().isEmpty(),
"Volumes binding is forbidden but found in machine '%s' of environment",
machineName);
checkArgument(
container.getNetworks() == null || container.getNetworks().isEmpty(),
"Networks configuration is forbidden but found in machine '%s' of environment",
machineName);
}
private void validateExtendedMachine(InternalMachineConfig machineConfig, String machineName)
throws ValidationException {
if (machineConfig.getServers() != null) {
for (Map.Entry<String, ? extends ServerConfig> serverEntry :
machineConfig.getServers().entrySet()) {
String serverName = serverEntry.getKey();
ServerConfig server = serverEntry.getValue();
checkArgument(
server.getPort() != null && SERVER_PORT.matcher(server.getPort()).matches(),
"Machine '%s' in environment contains server conf '%s' with invalid port '%s'",
machineName,
serverName,
server.getPort());
checkArgument(
server.getProtocol() == null || SERVER_PROTOCOL.matcher(server.getProtocol()).matches(),
"Machine '%s' in environment contains server conf '%s' with invalid protocol '%s'",
machineName,
serverName,
server.getProtocol());
}
}
}
}

View File

@ -0,0 +1,76 @@
/*
* Copyright (c) 2012-2017 Red Hat, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.workspace.infrastructure.docker.environment.convert;
import com.google.common.collect.Maps;
import java.util.LinkedHashMap;
import java.util.Map;
import org.eclipse.che.api.core.ValidationException;
import org.eclipse.che.api.workspace.server.spi.environment.InternalEnvironment;
import org.eclipse.che.workspace.infrastructure.docker.environment.compose.ComposeEnvironment;
import org.eclipse.che.workspace.infrastructure.docker.environment.compose.model.ComposeService;
import org.eclipse.che.workspace.infrastructure.docker.model.DockerBuildContext;
import org.eclipse.che.workspace.infrastructure.docker.model.DockerContainerConfig;
import org.eclipse.che.workspace.infrastructure.docker.model.DockerEnvironment;
/**
* Converts {@link ComposeEnvironment} to {@link DockerEnvironment}.
*
* @author Alexander Garagatyi
* @author Alexander Andrienko
*/
public class ComposeEnvironmentConverter implements DockerEnvironmentConverter {
@Override
public DockerEnvironment convert(InternalEnvironment environment) throws ValidationException {
if (!(environment instanceof ComposeEnvironment)) {
throw new ValidationException("The specified environment is not compose environment");
}
ComposeEnvironment composeEnv = (ComposeEnvironment) environment;
LinkedHashMap<String, DockerContainerConfig> containers =
Maps.newLinkedHashMapWithExpectedSize(composeEnv.getServices().size());
for (Map.Entry<String, ComposeService> composeServiceEntry :
composeEnv.getServices().entrySet()) {
ComposeService service = composeServiceEntry.getValue();
DockerContainerConfig cheContainer =
new DockerContainerConfig()
.setCommand(service.getCommand())
.setContainerName(service.getContainerName())
.setDependsOn(service.getDependsOn())
.setEntrypoint(service.getEntrypoint())
.setEnvironment(service.getEnvironment())
.setExpose(service.getExpose())
.setImage(service.getImage())
.setLabels(service.getLabels())
.setLinks(service.getLinks())
.setMemLimit(service.getMemLimit())
.setNetworks(service.getNetworks())
.setPorts(service.getPorts())
.setVolumes(service.getVolumes())
.setVolumesFrom(service.getVolumesFrom());
if (service.getBuild() != null) {
cheContainer.setBuild(
new DockerBuildContext()
.setContext(service.getBuild().getContext())
.setDockerfilePath(service.getBuild().getDockerfile())
.setArgs(service.getBuild().getArgs()));
}
containers.put(composeServiceEntry.getKey(), cheContainer);
}
return new DockerEnvironment(
environment.getRecipe(), environment.getMachines(), environment.getWarnings())
.setContainers(containers);
}
}

View File

@ -0,0 +1,31 @@
/*
* Copyright (c) 2012-2017 Red Hat, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.workspace.infrastructure.docker.environment.convert;
import org.eclipse.che.api.core.ValidationException;
import org.eclipse.che.api.workspace.server.spi.environment.InternalEnvironment;
import org.eclipse.che.workspace.infrastructure.docker.model.DockerEnvironment;
/**
* Converts {@link InternalEnvironment} into {@link DockerEnvironment}.
*
* @author Sergii Leshchenko
*/
public interface DockerEnvironmentConverter {
/**
* Returns {@link DockerEnvironment} that is converted from the specified {@link
* InternalEnvironment}.
*
* @param environment environment to converting
*/
DockerEnvironment convert(InternalEnvironment environment) throws ValidationException;
}

View File

@ -0,0 +1,34 @@
/*
* Copyright (c) 2012-2017 Red Hat, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.workspace.infrastructure.docker.environment.convert;
import com.google.inject.AbstractModule;
import com.google.inject.multibindings.MapBinder;
import org.eclipse.che.workspace.infrastructure.docker.environment.compose.ComposeEnvironment;
import org.eclipse.che.workspace.infrastructure.docker.environment.dockerfile.DockerfileEnvironment;
import org.eclipse.che.workspace.infrastructure.docker.environment.dockerimage.DockerImageEnvironment;
/** @author Alexander Garagatyi */
public class DockerEnvironmentConvertersModule extends AbstractModule {
@Override
protected void configure() {
// Environment type
MapBinder<String, DockerEnvironmentConverter> envParserMapBinder =
MapBinder.newMapBinder(binder(), String.class, DockerEnvironmentConverter.class);
envParserMapBinder.addBinding(ComposeEnvironment.TYPE).to(ComposeEnvironmentConverter.class);
envParserMapBinder
.addBinding(DockerfileEnvironment.TYPE)
.to(DockerfileEnvironmentConverter.class);
envParserMapBinder
.addBinding(DockerImageEnvironment.TYPE)
.to(DockerImageEnvironmentConverter.class);
}
}

View File

@ -0,0 +1,58 @@
/*
* Copyright (c) 2012-2017 Red Hat, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.workspace.infrastructure.docker.environment.convert;
import static org.eclipse.che.workspace.infrastructure.docker.ArgumentsValidator.checkArgument;
import com.google.common.base.Joiner;
import org.eclipse.che.api.core.ValidationException;
import org.eclipse.che.api.workspace.server.spi.environment.InternalEnvironment;
import org.eclipse.che.workspace.infrastructure.docker.environment.dockerimage.DockerImageEnvironment;
import org.eclipse.che.workspace.infrastructure.docker.model.DockerContainerConfig;
import org.eclipse.che.workspace.infrastructure.docker.model.DockerEnvironment;
/**
* Converts {@link DockerImageEnvironment} to {@link DockerEnvironment}.
*
* @author Alexander Garagatyi
* @author Alexander Andrienko
*/
public class DockerImageEnvironmentConverter implements DockerEnvironmentConverter {
@Override
public DockerEnvironment convert(InternalEnvironment environment) throws ValidationException {
if (!(environment instanceof DockerImageEnvironment)) {
throw new ValidationException("The specified environment is not docker image environment");
}
DockerImageEnvironment dockerImageEnv = (DockerImageEnvironment) environment;
String machineName = getMachineName(dockerImageEnv);
DockerContainerConfig container =
new DockerContainerConfig().setImage(dockerImageEnv.getDockerImage());
DockerEnvironment dockerEnv =
new DockerEnvironment(
environment.getRecipe(), environment.getMachines(), environment.getWarnings());
dockerEnv.getContainers().put(machineName, container);
return dockerEnv;
}
private String getMachineName(InternalEnvironment environment) throws ValidationException {
checkArgument(
environment.getMachines().size() == 1,
"Environment of type '%s' doesn't support multiple machines, but contains machines: %s",
environment.getRecipe().getType(),
Joiner.on(", ").join(environment.getMachines().keySet()));
return environment.getMachines().keySet().iterator().next();
}
}

View File

@ -0,0 +1,59 @@
/*
* Copyright (c) 2012-2017 Red Hat, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.workspace.infrastructure.docker.environment.convert;
import static org.eclipse.che.workspace.infrastructure.docker.ArgumentsValidator.checkArgument;
import com.google.common.base.Joiner;
import org.eclipse.che.api.core.ValidationException;
import org.eclipse.che.api.workspace.server.spi.environment.InternalEnvironment;
import org.eclipse.che.workspace.infrastructure.docker.environment.dockerfile.DockerfileEnvironment;
import org.eclipse.che.workspace.infrastructure.docker.model.DockerBuildContext;
import org.eclipse.che.workspace.infrastructure.docker.model.DockerContainerConfig;
import org.eclipse.che.workspace.infrastructure.docker.model.DockerEnvironment;
/**
* Converts {@link DockerfileEnvironment} to {@link DockerEnvironment}.
*
* @author Alexander Garagatyi
* @author Alexander Andrienko
*/
public class DockerfileEnvironmentConverter implements DockerEnvironmentConverter {
@Override
public DockerEnvironment convert(InternalEnvironment environment) throws ValidationException {
if (!(environment instanceof DockerfileEnvironment)) {
throw new ValidationException("The specified environment is not dockerfile environment");
}
DockerfileEnvironment dockerfileEnv = (DockerfileEnvironment) environment;
String machineName = getMachineName(dockerfileEnv);
String dockerfile = dockerfileEnv.getDockerfileContent();
DockerEnvironment cheContainerEnv =
new DockerEnvironment(
environment.getRecipe(), environment.getMachines(), environment.getWarnings());
DockerContainerConfig container =
new DockerContainerConfig()
.setBuild(new DockerBuildContext().setDockerfileContent(dockerfile));
cheContainerEnv.getContainers().put(machineName, container);
return cheContainerEnv;
}
private String getMachineName(InternalEnvironment environment) throws ValidationException {
checkArgument(
environment.getMachines().size() == 1,
"Environment of type '%s' doesn't support multiple machines, but contains machines: %s",
environment.getRecipe().getType(),
Joiner.on(", ").join(environment.getMachines().keySet()));
return environment.getMachines().keySet().iterator().next();
}
}

View File

@ -14,8 +14,7 @@ import javax.inject.Inject;
import javax.inject.Singleton;
import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity;
import org.eclipse.che.api.workspace.server.spi.InfrastructureException;
import org.eclipse.che.api.workspace.server.spi.environment.InternalEnvironment;
import org.eclipse.che.workspace.infrastructure.docker.InfrastructureProvisioner;
import org.eclipse.che.workspace.infrastructure.docker.DockerEnvironmentProvisioner;
import org.eclipse.che.workspace.infrastructure.docker.local.dod.DockerApiHostEnvVariableProvisioner;
import org.eclipse.che.workspace.infrastructure.docker.local.installer.LocalInstallersBinariesVolumeProvisioner;
import org.eclipse.che.workspace.infrastructure.docker.local.installer.WsAgentServerConfigProvisioner;
@ -34,7 +33,7 @@ import org.eclipse.che.workspace.infrastructure.docker.provisioner.server.Server
* @author Alexander Garagatyi
*/
@Singleton
public class LocalCheInfrastructureProvisioner implements InfrastructureProvisioner {
public class LocalCheDockerEnvironmentProvisioner implements DockerEnvironmentProvisioner {
private final ContainerSystemSettingsProvisionersApplier dockerSettingsProvisioners;
private final ProjectsVolumeProvisioner projectsVolumeProvisioner;
@ -47,7 +46,7 @@ public class LocalCheInfrastructureProvisioner implements InfrastructureProvisio
private final MemoryAttributeConverter memoryAttributeConverter;
@Inject
public LocalCheInfrastructureProvisioner(
public LocalCheDockerEnvironmentProvisioner(
ContainerSystemSettingsProvisionersApplier dockerSettingsProvisioners,
ProjectsVolumeProvisioner projectsVolumeProvisioner,
LocalInstallersBinariesVolumeProvisioner installersBinariesVolumeProvisioner,
@ -70,22 +69,21 @@ public class LocalCheInfrastructureProvisioner implements InfrastructureProvisio
}
@Override
public void provision(
InternalEnvironment envConfig, DockerEnvironment internalEnv, RuntimeIdentity identity)
public void provision(DockerEnvironment internalEnv, RuntimeIdentity identity)
throws InfrastructureException {
// 1 stage - add Che business logic items to Che model env
// 2 stage - converting Che model env to docker env
serversConverter.provision(envConfig, internalEnv, identity);
envVarsConverter.provision(envConfig, internalEnv, identity);
memoryAttributeConverter.provision(envConfig, internalEnv, identity);
serversConverter.provision(internalEnv, identity);
envVarsConverter.provision(internalEnv, identity);
memoryAttributeConverter.provision(internalEnv, identity);
// 3 stage - add docker env items
runtimeLabelsProvisioner.provision(envConfig, internalEnv, identity);
installersBinariesVolumeProvisioner.provision(envConfig, internalEnv, identity);
projectsVolumeProvisioner.provision(envConfig, internalEnv, identity);
dockerApiEnvProvisioner.provision(envConfig, internalEnv, identity);
wsAgentServerConfigProvisioner.provision(envConfig, internalEnv, identity);
dockerSettingsProvisioners.provision(envConfig, internalEnv, identity);
dockerApiEnvProvisioner.provision(envConfig, internalEnv, identity);
runtimeLabelsProvisioner.provision(internalEnv, identity);
installersBinariesVolumeProvisioner.provision(internalEnv, identity);
projectsVolumeProvisioner.provision(internalEnv, identity);
dockerApiEnvProvisioner.provision(internalEnv, identity);
wsAgentServerConfigProvisioner.provision(internalEnv, identity);
dockerSettingsProvisioners.provision(internalEnv, identity);
dockerApiEnvProvisioner.provision(internalEnv, identity);
}
}

View File

@ -16,7 +16,7 @@ import com.google.inject.AbstractModule;
import com.google.inject.multibindings.Multibinder;
import com.google.inject.name.Names;
import org.eclipse.che.infrastructure.docker.client.DockerRegistryChecker;
import org.eclipse.che.workspace.infrastructure.docker.InfrastructureProvisioner;
import org.eclipse.che.workspace.infrastructure.docker.DockerEnvironmentProvisioner;
import org.eclipse.che.workspace.infrastructure.docker.local.installer.ExecInstallerInfrastructureProvisioner;
import org.eclipse.che.workspace.infrastructure.docker.local.installer.TerminalInstallerInfrastructureProvisioner;
import org.eclipse.che.workspace.infrastructure.docker.local.installer.WsAgentBinariesInfrastructureProvisioner;
@ -34,7 +34,7 @@ public class LocalDockerModule extends AbstractModule {
bind(DockerRegistryChecker.class).asEagerSingleton();
bind(InfrastructureProvisioner.class).to(LocalCheInfrastructureProvisioner.class);
bind(DockerEnvironmentProvisioner.class).to(LocalCheDockerEnvironmentProvisioner.class);
Multibinder<ConfigurationProvisioner> localInstallersProvisioners =
Multibinder.newSetBinder(

View File

@ -17,7 +17,6 @@ import javax.inject.Inject;
import javax.inject.Singleton;
import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity;
import org.eclipse.che.api.workspace.server.spi.InfrastructureException;
import org.eclipse.che.api.workspace.server.spi.environment.InternalEnvironment;
import org.eclipse.che.infrastructure.docker.client.DockerConnectorConfiguration;
import org.eclipse.che.workspace.infrastructure.docker.model.DockerContainerConfig;
import org.eclipse.che.workspace.infrastructure.docker.model.DockerEnvironment;
@ -47,8 +46,7 @@ public class DockerApiHostEnvVariableProvisioner implements ConfigurationProvisi
}
@Override
public void provision(
InternalEnvironment envConfig, DockerEnvironment internalEnv, RuntimeIdentity identity)
public void provision(DockerEnvironment internalEnv, RuntimeIdentity identity)
throws InfrastructureException {
if (value != null) {

View File

@ -23,7 +23,6 @@ import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity;
import org.eclipse.che.api.core.util.SystemInfo;
import org.eclipse.che.api.installer.server.impl.InstallerFqn;
import org.eclipse.che.api.workspace.server.spi.InfrastructureException;
import org.eclipse.che.api.workspace.server.spi.environment.InternalEnvironment;
import org.eclipse.che.api.workspace.server.spi.environment.InternalMachineConfig;
import org.eclipse.che.workspace.infrastructure.docker.WindowsHostUtils;
import org.eclipse.che.workspace.infrastructure.docker.model.DockerContainerConfig;
@ -91,12 +90,11 @@ public abstract class InstallerBinariesInfrastructureProvisioner
}
@Override
public void provision(
InternalEnvironment envConfig, DockerEnvironment internalEnv, RuntimeIdentity identity)
public void provision(DockerEnvironment internalEnv, RuntimeIdentity identity)
throws InfrastructureException {
for (Map.Entry<String, InternalMachineConfig> machineConfigEntry :
envConfig.getMachines().entrySet()) {
internalEnv.getMachines().entrySet()) {
InternalMachineConfig machineConfig = machineConfigEntry.getValue();
if (InstallerFqn.idInInstallerList(installerFqn, machineConfig.getInstallers())) {

View File

@ -15,7 +15,6 @@ import javax.inject.Inject;
import javax.inject.Named;
import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity;
import org.eclipse.che.api.workspace.server.spi.InfrastructureException;
import org.eclipse.che.api.workspace.server.spi.environment.InternalEnvironment;
import org.eclipse.che.workspace.infrastructure.docker.model.DockerEnvironment;
import org.eclipse.che.workspace.infrastructure.docker.provisioner.ConfigurationProvisioner;
@ -39,12 +38,11 @@ public class LocalInstallersBinariesVolumeProvisioner implements ConfigurationPr
}
@Override
public void provision(
InternalEnvironment envConfig, DockerEnvironment internalEnv, RuntimeIdentity identity)
public void provision(DockerEnvironment internalEnv, RuntimeIdentity identity)
throws InfrastructureException {
for (ConfigurationProvisioner infrastructureProvisioner : localInstallerProvisioners) {
infrastructureProvisioner.provision(envConfig, internalEnv, identity);
infrastructureProvisioner.provision(internalEnv, identity);
}
}
}

View File

@ -16,7 +16,6 @@ import javax.inject.Singleton;
import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity;
import org.eclipse.che.api.workspace.server.WsAgentMachineFinderUtil;
import org.eclipse.che.api.workspace.server.spi.InfrastructureException;
import org.eclipse.che.api.workspace.server.spi.environment.InternalEnvironment;
import org.eclipse.che.inject.CheBootstrap;
import org.eclipse.che.workspace.infrastructure.docker.local.server.DockerExtConfBindingProvider;
import org.eclipse.che.workspace.infrastructure.docker.model.DockerContainerConfig;
@ -40,8 +39,7 @@ public class WsAgentServerConfigProvisioner implements ConfigurationProvisioner
}
@Override
public void provision(
InternalEnvironment envConfig, DockerEnvironment internalEnv, RuntimeIdentity identity)
public void provision(DockerEnvironment internalEnv, RuntimeIdentity identity)
throws InfrastructureException {
if (extConfBinding == null) {
@ -49,7 +47,7 @@ public class WsAgentServerConfigProvisioner implements ConfigurationProvisioner
return;
}
Optional<String> devMachineOptional =
WsAgentMachineFinderUtil.getWsAgentServerMachine(envConfig);
WsAgentMachineFinderUtil.getWsAgentServerMachine(internalEnv);
if (!devMachineOptional.isPresent()) {
// no wsagent server found - do nothing
return;

View File

@ -22,7 +22,6 @@ import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity;
import org.eclipse.che.api.core.util.SystemInfo;
import org.eclipse.che.api.workspace.server.WsAgentMachineFinderUtil;
import org.eclipse.che.api.workspace.server.spi.InfrastructureException;
import org.eclipse.che.api.workspace.server.spi.environment.InternalEnvironment;
import org.eclipse.che.api.workspace.server.spi.InternalInfrastructureException;
import org.eclipse.che.commons.annotation.Nullable;
import org.eclipse.che.commons.lang.os.WindowsPathEscaper;
@ -63,11 +62,10 @@ public class ProjectsVolumeProvisioner implements ConfigurationProvisioner {
}
@Override
public void provision(
InternalEnvironment envConfig, DockerEnvironment internalEnv, RuntimeIdentity identity)
public void provision(DockerEnvironment internalEnv, RuntimeIdentity identity)
throws InfrastructureException {
Optional<String> devMachineOpt = WsAgentMachineFinderUtil.getWsAgentServerMachine(envConfig);
Optional<String> devMachineOpt = WsAgentMachineFinderUtil.getWsAgentServerMachine(internalEnv);
if (!devMachineOpt.isPresent()) {
// should not happen
// no wsagent - no projects volume is needed

View File

@ -270,15 +270,15 @@ public class DockerContainerConfig {
}
/**
* Expose ports without publishing them to the host machine - theyll only be accessible to linked
* containers.
* Immutable expose ports list without publishing them to the host machine - theyll only be
* accessible to linked containers.
*
* <p>Only the internal port can be specified. <br>
* Examples:
*
* <ul>
* <li>3000
* <li>8000
* <li>3000/tcp
* <li>8000/udp
* </ul>
*/
public Set<String> getExpose() {
@ -301,6 +301,13 @@ public class DockerContainerConfig {
return this;
}
public void addExpose(String exposeToAdd) {
if (expose == null) {
expose = new HashSet<>();
}
expose.add(normalizeExposeValue(exposeToAdd));
}
private String normalizeExposeValue(String expose) {
return expose.contains("/") ? expose : expose + "/tcp";
}

View File

@ -10,12 +10,10 @@
*/
package org.eclipse.che.workspace.infrastructure.docker.model;
import static java.util.stream.Collectors.toMap;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import org.eclipse.che.api.core.model.workspace.Warning;
import org.eclipse.che.api.workspace.server.spi.InfrastructureException;
@ -29,7 +27,7 @@ import org.eclipse.che.api.workspace.server.spi.environment.InternalRecipe;
* @author Alexander Garagatyi
*/
public class DockerEnvironment extends InternalEnvironment {
private Map<String, DockerContainerConfig> containers;
private LinkedHashMap<String, DockerContainerConfig> containers;
private String network;
public DockerEnvironment() {}
@ -43,7 +41,7 @@ public class DockerEnvironment extends InternalEnvironment {
InternalRecipe recipe,
Map<String, InternalMachineConfig> machines,
List<Warning> warnings,
Map<String, DockerContainerConfig> containers,
LinkedHashMap<String, DockerContainerConfig> containers,
String network)
throws InfrastructureException {
super(recipe, machines, warnings);
@ -54,27 +52,26 @@ public class DockerEnvironment extends InternalEnvironment {
public DockerEnvironment(DockerEnvironment environment) throws InfrastructureException {
super(environment.getRecipe(), environment.getMachines(), environment.getWarnings());
if (environment.getContainers() != null) {
containers =
environment
.getContainers()
.entrySet()
.stream()
.collect(
toMap(Map.Entry::getKey, entry -> new DockerContainerConfig(entry.getValue())));
containers = new LinkedHashMap<>();
for (Entry<String, DockerContainerConfig> containerEntry :
environment.getContainers().entrySet()) {
containers.put(
containerEntry.getKey(), new DockerContainerConfig(containerEntry.getValue()));
}
}
}
/** Ordered mapping of containers names to containers configuration. */
public Map<String, DockerContainerConfig> getContainers() {
public LinkedHashMap<String, DockerContainerConfig> getContainers() {
if (containers == null) {
containers = new LinkedHashMap<>();
}
return containers;
}
public DockerEnvironment setContainers(Map<String, DockerContainerConfig> containers) {
public DockerEnvironment setContainers(LinkedHashMap<String, DockerContainerConfig> containers) {
if (containers != null) {
containers = new HashMap<>(containers);
containers = new LinkedHashMap<>(containers);
}
this.containers = containers;
return this;

View File

@ -12,18 +12,17 @@ package org.eclipse.che.workspace.infrastructure.docker.provisioner;
import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity;
import org.eclipse.che.api.workspace.server.spi.InfrastructureException;
import org.eclipse.che.api.workspace.server.spi.environment.InternalEnvironment;
import org.eclipse.che.workspace.infrastructure.docker.DockerEnvironmentProvisioner;
import org.eclipse.che.workspace.infrastructure.docker.DockerRuntimeInfrastructure;
import org.eclipse.che.workspace.infrastructure.docker.InfrastructureProvisioner;
import org.eclipse.che.workspace.infrastructure.docker.model.DockerEnvironment;
/**
* Modifies environment of workspace with everything needed for some logical part of {@link
* DockerRuntimeInfrastructure}. It is supposed that some set of {@code ConfigurationProvisioner}s
* will be used to implement {@link InfrastructureProvisioner}. </br>Although it is identical to
* {@link InfrastructureProvisioner} it is separated from it not to mix implementations of {@code
* ConfigurationProvisioner} as parts of an {@code InfrastructureProvisioner} with implementations
* of {@code InfrastructureProvisioner}.
* will be used to implement {@link DockerEnvironmentProvisioner}. </br>Although it is identical to
* {@link DockerEnvironmentProvisioner} it is separated from it not to mix implementations of {@code
* ConfigurationProvisioner} as parts of an {@code DockerEnvironmentProvisioner} with
* implementations of {@code DockerEnvironmentProvisioner}.
*
* @author Alexander Garagatyi
*/
@ -32,11 +31,9 @@ public interface ConfigurationProvisioner {
* Modifies environment config and internal environment representation with everything needed for
* infrastructure of workspace.
*
* @param envConfig configuration of environment
* @param internalEnv internal environment representation
* @throws InfrastructureException if any error occurs
*/
void provision(
InternalEnvironment envConfig, DockerEnvironment internalEnv, RuntimeIdentity identity)
void provision(DockerEnvironment internalEnv, RuntimeIdentity identity)
throws InfrastructureException;
}

View File

@ -14,7 +14,6 @@ import java.util.Set;
import javax.inject.Inject;
import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity;
import org.eclipse.che.api.workspace.server.spi.InfrastructureException;
import org.eclipse.che.api.workspace.server.spi.environment.InternalEnvironment;
import org.eclipse.che.workspace.infrastructure.docker.model.DockerEnvironment;
/**
@ -33,8 +32,7 @@ public class ContainerSystemSettingsProvisionersApplier implements Configuration
}
@Override
public void provision(
InternalEnvironment envConfig, DockerEnvironment internalEnv, RuntimeIdentity identity)
public void provision(DockerEnvironment internalEnv, RuntimeIdentity identity)
throws InfrastructureException {
for (ContainerSystemSettingsProvisioner dockerSettingsProvisioner :
dockerSettingsProvisioners) {

View File

@ -13,8 +13,7 @@ package org.eclipse.che.workspace.infrastructure.docker.provisioner.env;
import org.eclipse.che.api.core.model.workspace.config.MachineConfig;
import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity;
import org.eclipse.che.api.workspace.server.spi.InfrastructureException;
import org.eclipse.che.api.workspace.server.spi.environment.InternalEnvironment;
import org.eclipse.che.workspace.infrastructure.docker.InfrastructureProvisioner;
import org.eclipse.che.workspace.infrastructure.docker.DockerEnvironmentProvisioner;
import org.eclipse.che.workspace.infrastructure.docker.model.DockerEnvironment;
/**
@ -22,14 +21,13 @@ import org.eclipse.che.workspace.infrastructure.docker.model.DockerEnvironment;
*
* @author Alexander Garagatyi
*/
public class EnvVarsConverter implements InfrastructureProvisioner {
public class EnvVarsConverter implements DockerEnvironmentProvisioner {
@Override
public void provision(
InternalEnvironment environment, DockerEnvironment internalEnv, RuntimeIdentity identity)
public void provision(DockerEnvironment internalEnv, RuntimeIdentity identity)
throws InfrastructureException {
environment
internalEnv
.getMachines()
.forEach(
(machineName, machineConfig) ->

View File

@ -13,7 +13,6 @@ package org.eclipse.che.workspace.infrastructure.docker.provisioner.labels;
import java.util.Map;
import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity;
import org.eclipse.che.api.workspace.server.spi.InfrastructureException;
import org.eclipse.che.api.workspace.server.spi.environment.InternalEnvironment;
import org.eclipse.che.api.workspace.server.spi.environment.InternalMachineConfig;
import org.eclipse.che.workspace.infrastructure.docker.Labels;
import org.eclipse.che.workspace.infrastructure.docker.model.DockerContainerConfig;
@ -27,11 +26,10 @@ import org.eclipse.che.workspace.infrastructure.docker.provisioner.Configuration
*/
public class RuntimeLabelsProvisioner implements ConfigurationProvisioner {
@Override
public void provision(
InternalEnvironment envConfig, DockerEnvironment internalEnv, RuntimeIdentity identity)
public void provision(DockerEnvironment internalEnv, RuntimeIdentity identity)
throws InfrastructureException {
for (Map.Entry<String, InternalMachineConfig> entry : envConfig.getMachines().entrySet()) {
for (Map.Entry<String, InternalMachineConfig> entry : internalEnv.getMachines().entrySet()) {
String name = entry.getKey();
DockerContainerConfig container = internalEnv.getContainers().get(name);
container

View File

@ -16,21 +16,19 @@ import java.util.Map.Entry;
import org.eclipse.che.api.core.model.workspace.config.MachineConfig;
import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity;
import org.eclipse.che.api.workspace.server.spi.InfrastructureException;
import org.eclipse.che.api.workspace.server.spi.environment.InternalEnvironment;
import org.eclipse.che.api.workspace.server.spi.environment.InternalMachineConfig;
import org.eclipse.che.workspace.infrastructure.docker.InfrastructureProvisioner;
import org.eclipse.che.workspace.infrastructure.docker.DockerEnvironmentProvisioner;
import org.eclipse.che.workspace.infrastructure.docker.model.DockerEnvironment;
/** @author Alexander Garagatyi */
public class MemoryAttributeConverter implements InfrastructureProvisioner {
public class MemoryAttributeConverter implements DockerEnvironmentProvisioner {
@Override
public void provision(
InternalEnvironment environment, DockerEnvironment internalEnv, RuntimeIdentity identity)
public void provision(DockerEnvironment internalEnv, RuntimeIdentity identity)
throws InfrastructureException {
for (Entry<String, ? extends InternalMachineConfig> machineEntry :
environment.getMachines().entrySet()) {
internalEnv.getMachines().entrySet()) {
String machineName = machineEntry.getKey();
InternalMachineConfig machineConfig = machineEntry.getValue();

View File

@ -14,8 +14,7 @@ import org.eclipse.che.api.core.model.workspace.config.ServerConfig;
import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity;
import org.eclipse.che.api.core.model.workspace.runtime.Server;
import org.eclipse.che.api.workspace.server.spi.InfrastructureException;
import org.eclipse.che.api.workspace.server.spi.environment.InternalEnvironment;
import org.eclipse.che.workspace.infrastructure.docker.InfrastructureProvisioner;
import org.eclipse.che.workspace.infrastructure.docker.DockerEnvironmentProvisioner;
import org.eclipse.che.workspace.infrastructure.docker.Labels;
import org.eclipse.che.workspace.infrastructure.docker.model.DockerContainerConfig;
import org.eclipse.che.workspace.infrastructure.docker.model.DockerEnvironment;
@ -28,18 +27,17 @@ import org.eclipse.che.workspace.infrastructure.docker.model.DockerEnvironment;
*
* @author Alexander Garagatyi
*/
public class ServersConverter implements InfrastructureProvisioner {
public class ServersConverter implements DockerEnvironmentProvisioner {
@Override
public void provision(
InternalEnvironment environment, DockerEnvironment internalEnv, RuntimeIdentity identity)
public void provision(DockerEnvironment environment, RuntimeIdentity identity)
throws InfrastructureException {
environment
.getMachines()
.forEach(
(machineName, machineConfig) -> {
DockerContainerConfig container = internalEnv.getContainers().get(machineName);
DockerContainerConfig container = environment.getContainers().get(machineName);
container
.getLabels()
@ -50,7 +48,7 @@ public class ServersConverter implements InfrastructureProvisioner {
.forEach(
(key, value) -> {
container.getPorts().add(value.getPort());
container.getExpose().add(value.getPort());
container.addExpose(value.getPort());
});
});
}