Propage env variables and memory limit on plugin brokering phase

Signed-off-by: Sergii Leshchenko <sleshche@redhat.com>
7.20.x
Sergii Leshchenko 2019-12-10 15:07:55 +02:00
parent 2b824713e6
commit 294cf4e609
27 changed files with 231 additions and 348 deletions

View File

@ -16,6 +16,7 @@ import java.util.Map;
import org.eclipse.che.api.core.model.workspace.config.Command;
import org.eclipse.che.api.core.model.workspace.config.Environment;
import org.eclipse.che.api.core.model.workspace.config.ProjectConfig;
import org.eclipse.che.api.core.model.workspace.devfile.Devfile;
import org.eclipse.che.commons.annotation.Nullable;
/**
@ -64,4 +65,7 @@ public interface WorkspaceConfig {
* values.
*/
Map<String, String> getAttributes();
/** Returns devfile that was to generating workspace config, null otherwise. */
Devfile getDevfile();
}

View File

@ -41,7 +41,6 @@ import java.util.stream.Collectors;
import javax.inject.Inject;
import javax.inject.Named;
import org.eclipse.che.api.core.model.workspace.config.ServerConfig;
import org.eclipse.che.api.core.model.workspace.devfile.Component;
import org.eclipse.che.api.core.model.workspace.devfile.Endpoint;
import org.eclipse.che.api.workspace.server.devfile.Constants;
import org.eclipse.che.api.workspace.server.devfile.FileContentProvider;
@ -51,6 +50,7 @@ import org.eclipse.che.api.workspace.server.model.impl.MachineConfigImpl;
import org.eclipse.che.api.workspace.server.model.impl.ServerConfigImpl;
import org.eclipse.che.api.workspace.server.model.impl.VolumeImpl;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
import org.eclipse.che.api.workspace.server.model.impl.devfile.ComponentImpl;
import org.eclipse.che.workspace.infrastructure.kubernetes.Names;
import org.eclipse.che.workspace.infrastructure.kubernetes.environment.KubernetesEnvironment;
import org.eclipse.che.workspace.infrastructure.kubernetes.util.Containers;
@ -103,7 +103,7 @@ public class DockerimageComponentToWorkspaceApplier implements ComponentToWorksp
@Override
public void apply(
WorkspaceConfigImpl workspaceConfig,
Component dockerimageComponent,
ComponentImpl dockerimageComponent,
FileContentProvider contentProvider)
throws DevfileException {
checkArgument(workspaceConfig != null, "Workspace config must not be null");

View File

@ -51,6 +51,7 @@ import org.eclipse.che.api.workspace.server.devfile.convert.component.ComponentT
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileException;
import org.eclipse.che.api.workspace.server.model.impl.MachineConfigImpl;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
import org.eclipse.che.api.workspace.server.model.impl.devfile.ComponentImpl;
import org.eclipse.che.commons.annotation.Nullable;
import org.eclipse.che.workspace.infrastructure.kubernetes.environment.KubernetesEnvironment;
import org.eclipse.che.workspace.infrastructure.kubernetes.environment.KubernetesEnvironment.PodData;
@ -134,7 +135,7 @@ public class KubernetesComponentToWorkspaceApplier implements ComponentToWorkspa
@Override
public void apply(
WorkspaceConfigImpl workspaceConfig,
Component k8sComponent,
ComponentImpl k8sComponent,
FileContentProvider contentProvider)
throws DevfileException {
checkArgument(workspaceConfig != null, "Workspace config must not be null");

View File

@ -272,7 +272,7 @@ public class JwtProxyProvisioner {
}
private InternalMachineConfig createJwtProxyMachine() {
return new InternalMachineConfig(null, emptyMap(), emptyMap(), attributes, null);
return new InternalMachineConfig(emptyMap(), emptyMap(), attributes, null);
}
private Pod createJwtProxyPod() {

View File

@ -32,13 +32,16 @@ import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import org.eclipse.che.api.core.model.workspace.devfile.Component;
import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity;
import org.eclipse.che.api.workspace.server.model.impl.CommandImpl;
import org.eclipse.che.api.workspace.server.model.impl.WarningImpl;
import org.eclipse.che.api.workspace.server.model.impl.devfile.ComponentImpl;
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;
@ -122,10 +125,33 @@ public class KubernetesPluginsToolingApplier implements ChePluginsApplier {
chePluginsVolumeApplier.applyVolumes(pod, k8sInitContainer, container.getVolumes(), k8sEnv);
}
Map<String, ComponentImpl> devfilePlugins =
k8sEnv
.getDevfile()
.getComponents()
.stream()
.filter(c -> c.getType().equals("cheEditor") || c.getType().equals("chePlugin"))
.collect(Collectors.toMap(ComponentImpl::getId, Function.identity()));
if (!devfilePlugins.containsKey(chePlugin.getId())) {
throw new InfrastructureException(
String.format(
"The downloaded plugin '%s' configuration does not have the "
+ "corresponding component in devfile. Devfile contains the following cheEditor/chePlugins: %s",
chePlugin.getId(), devfilePlugins.keySet()));
}
ComponentImpl pluginRelatedComponent = devfilePlugins.get(chePlugin.getId());
Collection<CommandImpl> pluginRelatedCommands = commandsResolver.resolve(chePlugin);
for (CheContainer container : chePlugin.getContainers()) {
addSidecar(pod, container, chePlugin, k8sEnv, pluginRelatedCommands, runtimeIdentity);
addSidecar(
pod,
container,
chePlugin,
k8sEnv,
pluginRelatedCommands,
pluginRelatedComponent,
runtimeIdentity);
}
}
@ -202,6 +228,7 @@ public class KubernetesPluginsToolingApplier implements ChePluginsApplier {
ChePlugin chePlugin,
KubernetesEnvironment k8sEnv,
Collection<CommandImpl> sidecarRelatedCommands,
Component pluginRelatedComponent,
RuntimeIdentity runtimeIdentity)
throws InfrastructureException {
@ -222,11 +249,8 @@ public class KubernetesPluginsToolingApplier implements ChePluginsApplier {
.setContainer(k8sContainer)
.setContainerEndpoints(containerEndpoints)
.setDefaultSidecarMemorySizeAttribute(defaultSidecarMemoryLimitBytes)
.setAttributes(k8sEnv.getAttributes())
.setProjectsRootPathEnvVar(projectsRootEnvVariableProvider.get(runtimeIdentity))
.setPluginPublisher(chePlugin.getPublisher())
.setPluginName(chePlugin.getName())
.setPluginId(chePlugin.getId())
.setComponent(pluginRelatedComponent)
.build();
InternalMachineConfig machineConfig = machineResolver.resolve();

View File

@ -13,26 +13,20 @@ package org.eclipse.che.workspace.infrastructure.kubernetes.wsplugins;
import static com.google.common.base.Strings.isNullOrEmpty;
import static java.lang.String.format;
import static java.util.Arrays.asList;
import static java.util.stream.Collectors.toMap;
import static org.eclipse.che.api.core.model.workspace.config.MachineConfig.DEVFILE_COMPONENT_ALIAS_ATTRIBUTE;
import static org.eclipse.che.api.core.model.workspace.config.MachineConfig.MEMORY_LIMIT_ATTRIBUTE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.EDITOR_COMPONENT_ALIAS_WORKSPACE_ATTRIBUTE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.PLUGINS_COMPONENTS_ALIASES_WORKSPACE_ATTRIBUTE;
import static org.eclipse.che.api.workspace.shared.Constants.PROJECTS_VOLUME_NAME;
import static org.eclipse.che.api.workspace.shared.Constants.SIDECAR_ENV_VARIABLES_ATTR_TEMPLATE;
import static org.eclipse.che.api.workspace.shared.Constants.SIDECAR_MEMORY_LIMIT_ATTR_TEMPLATE;
import io.fabric8.kubernetes.api.model.Container;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.stream.Stream;
import java.util.stream.Collectors;
import org.eclipse.che.api.core.model.workspace.config.ServerConfig;
import org.eclipse.che.api.core.model.workspace.devfile.Component;
import org.eclipse.che.api.core.model.workspace.devfile.Env;
import org.eclipse.che.api.workspace.server.model.impl.ServerConfigImpl;
import org.eclipse.che.api.workspace.server.model.impl.VolumeImpl;
import org.eclipse.che.api.workspace.server.spi.InfrastructureException;
@ -47,105 +41,57 @@ import org.eclipse.che.workspace.infrastructure.kubernetes.util.KubernetesSize;
/** @author Oleksandr Garagatyi */
public class MachineResolver {
private final String pluginPublisherAndName;
private final String pluginId;
private final Container container;
private final CheContainer cheContainer;
private final String defaultSidecarMemoryLimitBytes;
private final List<ChePluginEndpoint> containerEndpoints;
private Map<String, String> wsAttributes;
private final Pair<String, String> projectsRootPathEnvVar;
private final Component component;
public MachineResolver(
String pluginPublisher,
String pluginName,
String pluginId,
Pair<String, String> projectsRootPathEnvVar,
Container container,
CheContainer cheContainer,
String defaultSidecarMemoryLimitBytes,
List<ChePluginEndpoint> containerEndpoints,
Map<String, String> wsAttributes) {
this.pluginPublisherAndName = pluginPublisher + "/" + pluginName;
this.pluginId = pluginId;
Component component) {
this.container = container;
this.cheContainer = cheContainer;
this.defaultSidecarMemoryLimitBytes = defaultSidecarMemoryLimitBytes;
this.containerEndpoints = containerEndpoints;
this.wsAttributes = wsAttributes != null ? wsAttributes : Collections.emptyMap();
this.projectsRootPathEnvVar = projectsRootPathEnvVar;
this.component = component;
}
public InternalMachineConfig resolve() throws InfrastructureException {
InternalMachineConfig machineConfig =
new InternalMachineConfig(
null,
toServers(containerEndpoints),
toEnvVariables(wsAttributes),
toMachineAttributes(pluginId, wsAttributes),
component.getEnv().stream().collect(Collectors.toMap(Env::getName, Env::getValue)),
resolveMachineAttributes(),
toWorkspaceVolumes(cheContainer));
normalizeMemory(container, machineConfig);
return machineConfig;
}
private Map<String,String> toEnvVariables(Map<String,String> wsAttributes) {
String envVars = wsAttributes
.get(format(SIDECAR_ENV_VARIABLES_ATTR_TEMPLATE, pluginPublisherAndName));
if (isNullOrEmpty(envVars)) {
return null;
}
return Stream.of(envVars.split(","))
// only splitting by 1'st '=' since env value may also contain it
.map(value -> value.split("=", 2))
.collect(toMap(arr -> arr[0], arr -> arr[1]));
}
private Map<String, String> toMachineAttributes(
String pluginId, Map<String, String> wsAttributes) {
private Map<String, String> resolveMachineAttributes() {
Map<String, String> attributes = new HashMap<>();
Optional<String> pluginAlias = findPluginAlias(pluginId, wsAttributes);
pluginAlias.ifPresent(s -> attributes.put(DEVFILE_COMPONENT_ALIAS_ATTRIBUTE, s));
String alias = component.getAlias();
if (alias != null) {
attributes.put(DEVFILE_COMPONENT_ALIAS_ATTRIBUTE, alias);
}
return attributes;
}
private Optional<String> findPluginAlias(String pluginId, Map<String, String> wsAttributes) {
List<String> aliases = new ArrayList<>();
String pluginComponentAliases =
wsAttributes.get(PLUGINS_COMPONENTS_ALIASES_WORKSPACE_ATTRIBUTE);
if (!isNullOrEmpty(pluginComponentAliases)) {
aliases.addAll(asList(pluginComponentAliases.split(",")));
}
String editorComponentAlias = wsAttributes.get(EDITOR_COMPONENT_ALIAS_WORKSPACE_ATTRIBUTE);
if (!isNullOrEmpty(editorComponentAlias)) {
aliases.add(editorComponentAlias);
}
if (aliases.isEmpty()) {
return Optional.empty();
}
return aliases
.stream()
.map(value -> value.split("="))
.filter(arr -> arr[0].equals(pluginId))
.map(arr -> arr[1])
.findAny();
}
private void normalizeMemory(Container container, InternalMachineConfig machineConfig) {
long ramLimit = Containers.getRamLimit(container);
if (ramLimit == 0) {
machineConfig.getAttributes().put(MEMORY_LIMIT_ATTRIBUTE, defaultSidecarMemoryLimitBytes);
}
// Use plugin_publisher/plugin_name to find overriding of memory limit.
String overriddenSidecarMemLimit =
wsAttributes.get(format(SIDECAR_MEMORY_LIMIT_ATTR_TEMPLATE, pluginPublisherAndName));
String overriddenSidecarMemLimit = component.getMemoryLimit();
if (!isNullOrEmpty(overriddenSidecarMemLimit)) {
machineConfig
.getAttributes()
@ -174,7 +120,7 @@ public class MachineResolver {
+ " the mountSources attribute to true instead and remove the manual volume"
+ " mount in the plugin. After that the mount path of the sources will be"
+ " available automatically in the '%s' environment variable.",
pluginPublisherAndName,
component.getId(),
PROJECTS_VOLUME_NAME,
container.getName(),
volume.getMountPath(),

View File

@ -13,7 +13,7 @@ package org.eclipse.che.workspace.infrastructure.kubernetes.wsplugins;
import io.fabric8.kubernetes.api.model.Container;
import java.util.List;
import java.util.Map;
import org.eclipse.che.api.core.model.workspace.devfile.Component;
import org.eclipse.che.api.workspace.server.wsplugins.model.CheContainer;
import org.eclipse.che.api.workspace.server.wsplugins.model.ChePluginEndpoint;
import org.eclipse.che.commons.lang.Pair;
@ -25,35 +25,25 @@ public class MachineResolverBuilder {
private CheContainer cheContainer;
private String defaultSidecarMemorySizeAttribute;
private List<ChePluginEndpoint> containerEndpoints;
private Map<String, String> wsAttributes;
private Pair<String, String> projectsRootPathEnvVar;
private String pluginPublisher;
private String pluginName;
private String pluginId;
private Component component;
public MachineResolver build() {
if (container == null
|| cheContainer == null
|| defaultSidecarMemorySizeAttribute == null
|| wsAttributes == null
|| containerEndpoints == null
|| projectsRootPathEnvVar == null
|| pluginPublisher == null
|| pluginName == null
|| pluginId == null) {
|| projectsRootPathEnvVar == null) {
throw new IllegalStateException();
}
return new MachineResolver(
pluginPublisher,
pluginName,
pluginId,
projectsRootPathEnvVar,
container,
cheContainer,
defaultSidecarMemorySizeAttribute,
containerEndpoints,
wsAttributes);
component);
}
public MachineResolverBuilder setContainer(Container container) {
@ -77,29 +67,14 @@ public class MachineResolverBuilder {
return this;
}
public MachineResolverBuilder setAttributes(Map<String, String> wsConfigAttributes) {
this.wsAttributes = wsConfigAttributes;
return this;
}
public MachineResolverBuilder setProjectsRootPathEnvVar(
Pair<String, String> projectsRootPathEnvVar) {
this.projectsRootPathEnvVar = projectsRootPathEnvVar;
return this;
}
public MachineResolverBuilder setPluginPublisher(String pluginPublisher) {
this.pluginPublisher = pluginPublisher;
return this;
}
public MachineResolverBuilder setPluginName(String pluginName) {
this.pluginName = pluginName;
return this;
}
public MachineResolverBuilder setPluginId(String pluginId) {
this.pluginId = pluginId;
public MachineResolverBuilder setComponent(Component component) {
this.component = component;
return this;
}
}

View File

@ -127,8 +127,7 @@ public class TestObjects {
}
public InternalMachineConfig build() {
return new InternalMachineConfig(
new ArrayList<>(), new HashMap<>(), new HashMap<>(), new HashMap<>(), volumes);
return new InternalMachineConfig(new HashMap<>(), new HashMap<>(), new HashMap<>(), volumes);
}
}
}

View File

@ -61,6 +61,8 @@ 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.workspace.server.model.impl.CommandImpl;
import org.eclipse.che.api.workspace.server.model.impl.ServerConfigImpl;
import org.eclipse.che.api.workspace.server.model.impl.devfile.ComponentImpl;
import org.eclipse.che.api.workspace.server.model.impl.devfile.DevfileImpl;
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;
@ -72,6 +74,7 @@ import org.eclipse.che.api.workspace.server.wsplugins.model.ChePluginEndpoint;
import org.eclipse.che.api.workspace.server.wsplugins.model.Command;
import org.eclipse.che.api.workspace.server.wsplugins.model.EnvVar;
import org.eclipse.che.api.workspace.server.wsplugins.model.Volume;
import org.eclipse.che.commons.lang.NameGenerator;
import org.eclipse.che.commons.lang.Pair;
import org.eclipse.che.workspace.infrastructure.kubernetes.Warnings;
import org.eclipse.che.workspace.infrastructure.kubernetes.environment.KubernetesEnvironment;
@ -112,6 +115,7 @@ public class KubernetesPluginsToolingApplierTest {
@BeforeMethod
public void setUp() {
internalEnvironment = spy(KubernetesEnvironment.builder().build());
internalEnvironment.setDevfile(new DevfileImpl());
applier =
new KubernetesPluginsToolingApplier(
TEST_IMAGE_POLICY,
@ -164,6 +168,31 @@ public class KubernetesPluginsToolingApplierTest {
validateContainerNameName(envCommand.getAttributes().get(MACHINE_NAME_ATTRIBUTE), "container");
}
@Test(
expectedExceptions = InfrastructureException.class,
expectedExceptionsMessageRegExp =
"The downloaded plugin 'publisher/id/version' configuration does "
+ "not have the corresponding component in devfile. Devfile contains the following "
+ "cheEditor/chePlugins: \\[publisher/editor/1, publisher/plugin/1\\]")
public void shouldThrowExceptionWhenDownloadedPluginIsNotMatchedWitComponent() throws Exception {
// given
ChePlugin chePlugin = createChePlugin("publisher/id/version");
internalEnvironment.getDevfile().getComponents().clear();
internalEnvironment
.getDevfile()
.getComponents()
.add(new ComponentImpl("cheEditor", "publisher/editor/1"));
internalEnvironment
.getDevfile()
.getComponents()
.add(new ComponentImpl("chePlugin", "publisher/plugin/1"));
internalEnvironment.getDevfile().getComponents().add(new ComponentImpl("k8s", null));
// when
applier.apply(runtimeIdentity, internalEnvironment, singletonList(chePlugin));
}
@Test
public void shouldResolveMachineNameForCommandsInEnvironment() throws Exception {
// given
@ -192,7 +221,7 @@ public class KubernetesPluginsToolingApplierTest {
public void shouldFillInWarningIfChePluginDoesNotHaveAnyContainersButThereAreRelatedCommands()
throws Exception {
// given
ChePlugin chePlugin = createChePlugin("custom-name");
ChePlugin chePlugin = createChePlugin("somePublisher/custom-name/0.0.3");
String pluginRef = chePlugin.getId();
CommandImpl pluginCommand = new CommandImpl("test-command", "echo Hello World!", "custom");
@ -274,7 +303,7 @@ public class KubernetesPluginsToolingApplierTest {
// given
internalEnvironment.getMachines().clear();
ChePlugin chePlugin = createChePlugin("plugin1", createContainer("container1"));
ChePlugin chePlugin = createChePlugin("publisher/plugin1/0.2.1", createContainer("container1"));
// when
applier.apply(runtimeIdentity, internalEnvironment, singletonList(chePlugin));
@ -421,6 +450,7 @@ public class KubernetesPluginsToolingApplierTest {
@Test
public void createsPodAndAddToolingIfNoPodIsPresent() throws Exception {
internalEnvironment = spy(KubernetesEnvironment.builder().build());
internalEnvironment.setDevfile(new DevfileImpl());
Map<String, InternalMachineConfig> machines = new HashMap<>();
machines.put(USER_MACHINE_NAME, userMachineConfig);
internalEnvironment.getMachines().putAll(machines);
@ -814,18 +844,19 @@ public class KubernetesPluginsToolingApplierTest {
}
private ChePlugin createChePlugin(CheContainer... containers) {
return createChePlugin("some-name", containers);
return createChePlugin("publisher/" + NameGenerator.generate("name", 3) + "/0.0.1", containers);
}
private ChePlugin createChePlugin(String name, CheContainer... containers) {
String version = "0.0.3";
String publisher = "somePublisher";
private ChePlugin createChePlugin(String id, CheContainer... containers) {
String[] splittedId = id.split("/");
ChePlugin plugin = new ChePlugin();
plugin.setName(name);
plugin.setPublisher(publisher);
plugin.setId(publisher + "/" + name + "/" + version);
plugin.setVersion(version);
plugin.setPublisher(splittedId[0]);
plugin.setName(splittedId[1]);
plugin.setVersion(splittedId[2]);
plugin.setId(id);
plugin.setContainers(Arrays.asList(containers));
internalEnvironment.getDevfile().getComponents().add(new ComponentImpl("chePlugin", id));
return plugin;
}

View File

@ -12,23 +12,20 @@
package org.eclipse.che.workspace.infrastructure.kubernetes.wsplugins;
import static com.google.common.collect.ImmutableMap.of;
import static java.lang.String.format;
import static java.util.Arrays.asList;
import static org.eclipse.che.api.core.model.workspace.config.MachineConfig.DEVFILE_COMPONENT_ALIAS_ATTRIBUTE;
import static org.eclipse.che.api.core.model.workspace.config.MachineConfig.MEMORY_LIMIT_ATTRIBUTE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.EDITOR_COMPONENT_ALIAS_WORKSPACE_ATTRIBUTE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.PLUGINS_COMPONENTS_ALIASES_WORKSPACE_ATTRIBUTE;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNull;
import io.fabric8.kubernetes.api.model.Container;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.che.api.core.model.workspace.config.ServerConfig;
import org.eclipse.che.api.workspace.server.model.impl.ServerConfigImpl;
import org.eclipse.che.api.workspace.server.model.impl.VolumeImpl;
import org.eclipse.che.api.workspace.server.model.impl.devfile.ComponentImpl;
import org.eclipse.che.api.workspace.server.model.impl.devfile.EnvImpl;
import org.eclipse.che.api.workspace.server.spi.InfrastructureException;
import org.eclipse.che.api.workspace.server.spi.environment.InternalMachineConfig;
import org.eclipse.che.api.workspace.server.wsplugins.model.CheContainer;
@ -57,41 +54,25 @@ public class MachineResolverTest {
private static final String PROJECTS_MOUNT_PATH = "/wherever/i/may/roam";
private List<ChePluginEndpoint> endpoints;
private Map<String, String> wsAttributes;
private CheContainer cheContainer;
private Container container;
private MachineResolver resolver;
private ComponentImpl component;
@BeforeMethod
public void setUp() {
endpoints = new ArrayList<>();
cheContainer = new CheContainer();
container = new Container();
wsAttributes = new HashMap<>();
component = new ComponentImpl("chePlugin", PLUGIN_ID);
resolver =
new MachineResolver(
PLUGIN_PUBLISHER,
PLUGIN_NAME,
PLUGIN_ID,
new Pair<>(PROJECTS_ENV_VAR, PROJECTS_MOUNT_PATH),
container,
cheContainer,
DEFAULT_MEM_LIMIT,
endpoints,
wsAttributes);
}
@Test
public void shouldSetComponentAliasAttributeInMachineConfig() throws InfrastructureException {
String componentAlias = "mycomponent";
wsAttributes.put(
PLUGINS_COMPONENTS_ALIASES_WORKSPACE_ATTRIBUTE,
"another/foo/plugin=fooplugin," + PLUGIN_ID + "=" + componentAlias);
wsAttributes.put(EDITOR_COMPONENT_ALIAS_WORKSPACE_ATTRIBUTE, "some/theia/editor=myeditor");
InternalMachineConfig machineConfig = resolver.resolve();
assertEquals(
machineConfig.getAttributes().get(DEVFILE_COMPONENT_ALIAS_ATTRIBUTE), componentAlias);
component);
}
@Test(dataProvider = "serverProvider")
@ -151,10 +132,8 @@ public class MachineResolverTest {
@Test(dataProvider = "memoryAttributeProvider")
public void shouldSetMemoryLimitOfASidecarIfCorrespondingWSConfigAttributeIsSet(
String attributeValue, String expectedMemLimit) throws InfrastructureException {
wsAttributes.put(
format(Constants.SIDECAR_MEMORY_LIMIT_ATTR_TEMPLATE, PLUGIN_PUBLISHER_NAME),
attributeValue);
String memoryLimit, String expectedMemLimit) throws InfrastructureException {
component.setMemoryLimit(memoryLimit);
InternalMachineConfig machineConfig = resolver.resolve();
@ -175,18 +154,28 @@ public class MachineResolverTest {
@Test
public void shouldOverrideMemoryLimitOfASidecarIfCorrespondingWSConfigAttributeIsSet()
throws InfrastructureException {
String attributeValue = "300Mi";
String expectedMemLimit = toBytesString(attributeValue);
String memoryLimit = "300Mi";
String expectedMemLimit = toBytesString(memoryLimit);
Containers.addRamLimit(container, 123456789);
wsAttributes.put(
format(Constants.SIDECAR_MEMORY_LIMIT_ATTR_TEMPLATE, PLUGIN_PUBLISHER_NAME),
attributeValue);
component.setMemoryLimit(memoryLimit);
InternalMachineConfig machineConfig = resolver.resolve();
assertEquals(machineConfig.getAttributes().get(MEMORY_LIMIT_ATTRIBUTE), expectedMemLimit);
}
@Test
public void
shouldProvisionEnvironmentVarsIntoMachineConfigOfASidecarIfTheyAreSetInTheCorrespondingComponent()
throws InfrastructureException {
component.getEnv().add(new EnvImpl("test", "value"));
InternalMachineConfig machineConfig = resolver.resolve();
assertEquals(machineConfig.getEnv().size(), 1);
assertEquals(machineConfig.getEnv().get("test"), "value");
}
@Test
public void shouldNotSetMemLimitAttributeIfLimitIsInContainer() throws InfrastructureException {
Containers.addRamLimit(container, 123456789);

View File

@ -113,16 +113,6 @@ public final class Constants {
*/
public static final String WORKSPACE_TOOLING_PLUGINS_ATTRIBUTE = "plugins";
/**
* Template for workspace attribute key that sets sidecar limit in a plugin. %s should be replaced
* with pluginPublisher/pluginName. When plugin provides several sidecars this property sets the
* same limit for each sidecar, so is not that useful in such a case. Value format see {@link
* KubernetesSize}
*/
public static final String SIDECAR_MEMORY_LIMIT_ATTR_TEMPLATE = "sidecar.%s.memory_limit";
public static final String SIDECAR_ENV_VARIABLES_ATTR_TEMPLATE = "sidecar.%s.environment_variables";
/**
* Describes workspace runtimes which perform start/stop of this workspace. Should be set/read
* from {@link Workspace#getAttributes}

View File

@ -55,7 +55,6 @@ import org.eclipse.che.api.core.NotFoundException;
import org.eclipse.che.api.core.ServerException;
import org.eclipse.che.api.core.ValidationException;
import org.eclipse.che.api.core.model.workspace.Workspace;
import org.eclipse.che.api.core.model.workspace.WorkspaceConfig;
import org.eclipse.che.api.core.model.workspace.WorkspaceStatus;
import org.eclipse.che.api.core.model.workspace.config.Command;
import org.eclipse.che.api.core.model.workspace.config.Environment;
@ -69,7 +68,9 @@ import org.eclipse.che.api.workspace.server.hc.probe.ProbeScheduler;
import org.eclipse.che.api.workspace.server.model.impl.CommandImpl;
import org.eclipse.che.api.workspace.server.model.impl.RuntimeIdentityImpl;
import org.eclipse.che.api.workspace.server.model.impl.RuntimeImpl;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceImpl;
import org.eclipse.che.api.workspace.server.model.impl.devfile.DevfileImpl;
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.InternalRuntime;
@ -216,8 +217,7 @@ public class WorkspaceRuntimes {
*/
public void validate(WorkspaceImpl workspace, @Nullable String envName)
throws ValidationException, NotFoundException, ServerException {
WorkspaceConfig config = workspace.getConfig();
WorkspaceConfigImpl config = workspace.getConfig();
if (workspace.getDevfile() != null) {
config = devfileConverter.convert(workspace.getDevfile());
}
@ -264,7 +264,7 @@ public class WorkspaceRuntimes {
// try to create internal environment to check if the specified environment is valid
try {
createInternalEnvironment(environment, emptyMap(), emptyList());
createInternalEnvironment(environment, emptyMap(), emptyList(), config.getDevfile());
} catch (InfrastructureException e) {
throw new ServerException(e.getMessage(), e);
}
@ -417,7 +417,7 @@ public class WorkspaceRuntimes {
workspace.getName()));
}
WorkspaceConfig config = workspace.getConfig();
WorkspaceConfigImpl config = workspace.getConfig();
if (config == null) {
config = devfileConverter.convert(workspace.getDevfile());
}
@ -447,7 +447,10 @@ public class WorkspaceRuntimes {
try {
InternalEnvironment internalEnv =
createInternalEnvironment(
config.getEnvironments().get(envName), config.getAttributes(), config.getCommands());
config.getEnvironments().get(envName),
config.getAttributes(),
config.getCommands(),
config.getDevfile());
RuntimeContext runtimeContext = infrastructure.prepare(runtimeId, internalEnv);
InternalRuntime runtime = runtimeContext.getRuntime();
@ -672,7 +675,7 @@ public class WorkspaceRuntimes {
+ "no more workspaces are allowed to start",
identity.getWorkspaceId()));
}
Workspace workspace;
WorkspaceImpl workspace;
try {
workspace = workspaceDao.get(identity.getWorkspaceId());
} catch (NotFoundException x) {
@ -683,7 +686,7 @@ public class WorkspaceRuntimes {
}
Environment environment = null;
WorkspaceConfig workspaceConfig = workspace.getConfig();
WorkspaceConfigImpl workspaceConfig = workspace.getConfig();
if (workspaceConfig == null) {
workspaceConfig = devfileConverter.convert(workspace.getDevfile());
}
@ -702,7 +705,10 @@ public class WorkspaceRuntimes {
try {
InternalEnvironment internalEnv =
createInternalEnvironment(
environment, workspaceConfig.getAttributes(), workspaceConfig.getCommands());
environment,
workspaceConfig.getAttributes(),
workspaceConfig.getCommands(),
workspaceConfig.getDevfile());
runtime = infra.prepare(identity, internalEnv).getRuntime();
WorkspaceStatus runtimeStatus = runtime.getStatus();
@ -727,7 +733,8 @@ public class WorkspaceRuntimes {
InternalEnvironment createInternalEnvironment(
@Nullable Environment environment,
Map<String, String> workspaceConfigAttributes,
List<? extends Command> commands)
List<? extends Command> commands,
DevfileImpl devfile)
throws InfrastructureException, ValidationException, NotFoundException {
String recipeType;
if (environment == null) {
@ -743,6 +750,7 @@ public class WorkspaceRuntimes {
InternalEnvironment internalEnvironment = factory.create(environment);
internalEnvironment.setAttributes(new HashMap<>(workspaceConfigAttributes));
internalEnvironment.setCommands(commands.stream().map(CommandImpl::new).collect(toList()));
internalEnvironment.setDevfile(devfile);
return internalEnvironment;
}

View File

@ -40,22 +40,6 @@ public class Constants {
/** Action type that should be used for commands execution. */
public static final String EXEC_ACTION_TYPE = "exec";
/**
* Workspace config attribute which contains comma-separated list of mappings of chePlugin
* component id to its name.
*
* <p>Example value:
*
* <pre>
* eclipse/maven-jdk8/1.0.0=mvn-stack,eclipse/theia-jdtls/0.0.3=jdt.ls
* </pre>
*/
public static final String PLUGINS_COMPONENTS_ALIASES_WORKSPACE_ATTRIBUTE =
"pluginComponentsAliases";
/** Workspace config attribute which contains cheEditor component name. */
public static final String EDITOR_COMPONENT_ALIAS_WORKSPACE_ATTRIBUTE = "editorComponentAlias";
/** Workspace command attributes that indicates with which component it is associated. */
public static final String COMPONENT_ALIAS_COMMAND_ATTRIBUTE = "componentAlias";

View File

@ -20,9 +20,7 @@ import com.google.common.base.Strings;
import java.util.Map;
import javax.inject.Inject;
import org.eclipse.che.api.core.ServerException;
import org.eclipse.che.api.core.model.workspace.WorkspaceConfig;
import org.eclipse.che.api.core.model.workspace.devfile.Command;
import org.eclipse.che.api.core.model.workspace.devfile.Component;
import org.eclipse.che.api.core.model.workspace.devfile.Devfile;
import org.eclipse.che.api.workspace.server.devfile.DevfileRecipeFormatException;
import org.eclipse.che.api.workspace.server.devfile.FileContentProvider;
@ -34,6 +32,7 @@ import org.eclipse.che.api.workspace.server.devfile.exception.DevfileFormatExcep
import org.eclipse.che.api.workspace.server.model.impl.CommandImpl;
import org.eclipse.che.api.workspace.server.model.impl.ProjectConfigImpl;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
import org.eclipse.che.api.workspace.server.model.impl.devfile.ComponentImpl;
import org.eclipse.che.api.workspace.server.model.impl.devfile.DevfileImpl;
import org.eclipse.che.api.workspace.server.model.impl.devfile.ProjectImpl;
@ -65,7 +64,17 @@ public class DevfileConverter {
this.urlFileContentProvider = new URLFileContentProvider(null, urlFetcher);
}
public WorkspaceConfig convert(Devfile devfile) throws ServerException {
/**
* Converts given {@link Devfile} into {@link WorkspaceConfigImpl workspace config}.
*
* <p>Note: some default components may be provisioned into devfile. The final devfile is
* accessible via {@link WorkspaceConfigImpl#getDevfile()}.
*
* @param devfile initial devfile
* @return constructed workspace config
* @throws ServerException when general devfile error occurs
*/
public WorkspaceConfigImpl convert(Devfile devfile) throws ServerException {
try {
return devFileToWorkspaceConfig(
new DevfileImpl(devfile), FileContentProvider.cached(urlFileContentProvider));
@ -112,7 +121,7 @@ public class DevfileConverter {
// note that component applier modifies commands in workspace config
// so, commands should be already converted
for (Component component : devfile.getComponents()) {
for (ComponentImpl component : devfile.getComponents()) {
ComponentToWorkspaceApplier applier = componentTypeToApplier.get(component.getType());
if (applier == null) {
throw new DevfileException(
@ -130,6 +139,8 @@ public class DevfileConverter {
config.getAttributes().putAll(devfile.getAttributes());
config.setDevfile(devfile);
return config;
}

View File

@ -11,10 +11,10 @@
*/
package org.eclipse.che.api.workspace.server.devfile.convert.component;
import org.eclipse.che.api.core.model.workspace.devfile.Component;
import org.eclipse.che.api.workspace.server.devfile.FileContentProvider;
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileException;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
import org.eclipse.che.api.workspace.server.model.impl.devfile.ComponentImpl;
/**
* Applies changes on workspace config according to the specified component. Different
@ -37,6 +37,8 @@ public interface ComponentToWorkspaceApplier {
* @throws DevfileException if any exception occurs during content retrieving
*/
void apply(
WorkspaceConfigImpl workspaceConfig, Component component, FileContentProvider contentProvider)
WorkspaceConfigImpl workspaceConfig,
ComponentImpl component,
FileContentProvider contentProvider)
throws DevfileException;
}

View File

@ -14,24 +14,18 @@ package org.eclipse.che.api.workspace.server.devfile.convert.component.editor;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Strings.isNullOrEmpty;
import static java.lang.String.format;
import static java.util.stream.Collectors.toList;
import static org.eclipse.che.api.core.model.workspace.config.Command.PLUGIN_ATTRIBUTE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.COMPONENT_ALIAS_COMMAND_ATTRIBUTE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.EDITOR_COMPONENT_ALIAS_WORKSPACE_ATTRIBUTE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.EDITOR_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.shared.Constants.SIDECAR_ENV_VARIABLES_ATTR_TEMPLATE;
import static org.eclipse.che.api.workspace.shared.Constants.SIDECAR_MEMORY_LIMIT_ATTR_TEMPLATE;
import static org.eclipse.che.api.workspace.shared.Constants.WORKSPACE_TOOLING_EDITOR_ATTRIBUTE;
import java.util.List;
import javax.inject.Inject;
import org.eclipse.che.api.core.model.workspace.devfile.Component;
import org.eclipse.che.api.core.model.workspace.devfile.Env;
import org.eclipse.che.api.workspace.server.devfile.FileContentProvider;
import org.eclipse.che.api.workspace.server.devfile.convert.component.ComponentFQNParser;
import org.eclipse.che.api.workspace.server.devfile.convert.component.ComponentToWorkspaceApplier;
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileException;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
import org.eclipse.che.api.workspace.server.model.impl.devfile.ComponentImpl;
import org.eclipse.che.api.workspace.server.wsplugins.model.ExtendedPluginFQN;
/**
@ -61,7 +55,7 @@ public class EditorComponentToWorkspaceApplier implements ComponentToWorkspaceAp
@Override
public void apply(
WorkspaceConfigImpl workspaceConfig,
Component editorComponent,
ComponentImpl editorComponent,
FileContentProvider contentProvider)
throws DevfileException {
checkArgument(workspaceConfig != null, "Workspace config must not be null");
@ -73,20 +67,8 @@ public class EditorComponentToWorkspaceApplier implements ComponentToWorkspaceAp
final String editorComponentAlias = editorComponent.getAlias();
final String editorId = editorComponent.getId();
final String registryUrl = editorComponent.getRegistryUrl();
final String memoryLimit = editorComponent.getMemoryLimit();
final List<? extends Env> env = editorComponent.getEnv();
final ExtendedPluginFQN fqn = componentFQNParser.evaluateFQN(editorComponent, contentProvider);
if (editorComponentAlias != null) {
workspaceConfig
.getAttributes()
.put(
EDITOR_COMPONENT_ALIAS_WORKSPACE_ATTRIBUTE,
componentFQNParser.getCompositeId(
fqn.getRegistry() != null ? fqn.getRegistry().toString() : null, fqn.getId())
+ "="
+ editorComponentAlias);
}
if (!isNullOrEmpty(fqn.getReference())) {
workspaceConfig.getAttributes().put(WORKSPACE_TOOLING_EDITOR_ATTRIBUTE, fqn.getReference());
@ -97,11 +79,7 @@ public class EditorComponentToWorkspaceApplier implements ComponentToWorkspaceAp
WORKSPACE_TOOLING_EDITOR_ATTRIBUTE,
componentFQNParser.getCompositeId(registryUrl, editorId));
}
if (memoryLimit != null) {
workspaceConfig
.getAttributes()
.put(format(SIDECAR_MEMORY_LIMIT_ATTR_TEMPLATE, fqn.getPublisherAndName()), memoryLimit);
}
workspaceConfig
.getCommands()
.stream()
@ -112,13 +90,8 @@ public class EditorComponentToWorkspaceApplier implements ComponentToWorkspaceAp
c.getAttributes().get(COMPONENT_ALIAS_COMMAND_ATTRIBUTE)))
.forEach(c -> c.getAttributes().put(PLUGIN_ATTRIBUTE, fqn.getId()));
if (!env.isEmpty()) {
workspaceConfig.getAttributes()
.put(format(SIDECAR_ENV_VARIABLES_ATTR_TEMPLATE, fqn.getPublisherAndName()),
String.join(",", env.stream().map(
(java.util.function.Function<Env, String>) e -> e.getName() + "=" + e.getValue())
.collect(toList())));
}
// make sure id is set to be able to match component with plugin broker result
// when referenceContent is used
editorComponent.setId(fqn.getId());
}
}

View File

@ -14,25 +14,19 @@ package org.eclipse.che.api.workspace.server.devfile.convert.component.plugin;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Strings.isNullOrEmpty;
import static java.lang.String.format;
import static java.util.stream.Collectors.toList;
import static org.eclipse.che.api.core.model.workspace.config.Command.PLUGIN_ATTRIBUTE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.COMPONENT_ALIAS_COMMAND_ATTRIBUTE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.PLUGINS_COMPONENTS_ALIASES_WORKSPACE_ATTRIBUTE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.PLUGIN_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.shared.Constants.SIDECAR_ENV_VARIABLES_ATTR_TEMPLATE;
import static org.eclipse.che.api.workspace.shared.Constants.SIDECAR_MEMORY_LIMIT_ATTR_TEMPLATE;
import static org.eclipse.che.api.workspace.shared.Constants.WORKSPACE_TOOLING_PLUGINS_ATTRIBUTE;
import java.util.List;
import javax.inject.Inject;
import org.eclipse.che.api.core.model.workspace.devfile.Component;
import org.eclipse.che.api.core.model.workspace.devfile.Env;
import org.eclipse.che.api.workspace.server.devfile.FileContentProvider;
import org.eclipse.che.api.workspace.server.devfile.convert.component.ComponentFQNParser;
import org.eclipse.che.api.workspace.server.devfile.convert.component.ComponentToWorkspaceApplier;
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileException;
import org.eclipse.che.api.workspace.server.model.impl.CommandImpl;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
import org.eclipse.che.api.workspace.server.model.impl.devfile.ComponentImpl;
import org.eclipse.che.api.workspace.server.wsplugins.model.ExtendedPluginFQN;
import org.eclipse.che.commons.annotation.Nullable;
@ -63,7 +57,7 @@ public class PluginComponentToWorkspaceApplier implements ComponentToWorkspaceAp
@Override
public void apply(
WorkspaceConfigImpl workspaceConfig,
Component pluginComponent,
ComponentImpl pluginComponent,
@Nullable FileContentProvider contentProvider)
throws DevfileException {
checkArgument(workspaceConfig != null, "Workspace config must not be null");
@ -94,12 +88,6 @@ public class PluginComponentToWorkspaceApplier implements ComponentToWorkspaceAp
workspacePluginsAttribute,
componentFQNParser.getCompositeId(registryUrl, pluginId)));
}
String memoryLimit = pluginComponent.getMemoryLimit();
if (memoryLimit != null) {
workspaceConfig
.getAttributes()
.put(format(SIDECAR_MEMORY_LIMIT_ATTR_TEMPLATE, fqn.getPublisherAndName()), memoryLimit);
}
for (CommandImpl command : workspaceConfig.getCommands()) {
String commandComponent = command.getAttributes().get(COMPONENT_ALIAS_COMMAND_ATTRIBUTE);
@ -116,30 +104,9 @@ public class PluginComponentToWorkspaceApplier implements ComponentToWorkspaceAp
command.getAttributes().put(PLUGIN_ATTRIBUTE, fqn.getId());
}
String pluginsAliases =
workspaceConfig.getAttributes().get(PLUGINS_COMPONENTS_ALIASES_WORKSPACE_ATTRIBUTE);
if (pluginComponent.getAlias() != null) {
workspaceConfig
.getAttributes()
.put(
PLUGINS_COMPONENTS_ALIASES_WORKSPACE_ATTRIBUTE,
append(
pluginsAliases,
componentFQNParser.getCompositeId(
fqn.getRegistry() != null ? fqn.getRegistry().toString() : null,
fqn.getId())
+ "="
+ pluginComponent.getAlias()));
}
final List<? extends Env> env = pluginComponent.getEnv();
if (!env.isEmpty()) {
workspaceConfig.getAttributes()
.put(format(SIDECAR_ENV_VARIABLES_ATTR_TEMPLATE, fqn.getPublisherAndName()),
String.join(",", env.stream().map(
(java.util.function.Function<Env, String>) e -> e.getName() + "=" + e.getValue())
.collect(toList())));
}
// make sure id is set to be able to match component with plugin broker result
// when referenceContent is used
pluginComponent.setId(fqn.getId());
}
private String append(String source, String toAppend) {

View File

@ -32,10 +32,13 @@ import javax.persistence.JoinColumn;
import javax.persistence.MapKeyColumn;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Transient;
import org.eclipse.che.api.core.model.workspace.WorkspaceConfig;
import org.eclipse.che.api.core.model.workspace.config.Command;
import org.eclipse.che.api.core.model.workspace.config.Environment;
import org.eclipse.che.api.core.model.workspace.config.ProjectConfig;
import org.eclipse.che.api.core.model.workspace.devfile.Devfile;
import org.eclipse.che.api.workspace.server.model.impl.devfile.DevfileImpl;
import org.eclipse.che.commons.annotation.Nullable;
/**
@ -87,6 +90,10 @@ public class WorkspaceConfigImpl implements WorkspaceConfig {
@Column(name = "attributes")
private Map<String, String> attributes;
// we do not store converted workspace configs,
// so it's not needed to store devfile from which this workspace config is generated
@Transient private DevfileImpl devfile;
public WorkspaceConfigImpl() {}
public WorkspaceConfigImpl(
@ -97,6 +104,18 @@ public class WorkspaceConfigImpl implements WorkspaceConfig {
List<? extends ProjectConfig> projects,
Map<String, ? extends Environment> environments,
Map<String, String> attributes) {
this(name, description, defaultEnv, commands, projects, environments, attributes, null);
}
public WorkspaceConfigImpl(
String name,
String description,
String defaultEnv,
List<? extends Command> commands,
List<? extends ProjectConfig> projects,
Map<String, ? extends Environment> environments,
Map<String, String> attributes,
Devfile devfile) {
this.name = name;
this.defaultEnv = defaultEnv;
this.description = description;
@ -116,6 +135,9 @@ public class WorkspaceConfigImpl implements WorkspaceConfig {
if (attributes != null) {
this.attributes = new HashMap<>(attributes);
}
if (devfile != null) {
this.devfile = new DevfileImpl(devfile);
}
}
public WorkspaceConfigImpl(WorkspaceConfig workspaceConfig) {
@ -126,7 +148,8 @@ public class WorkspaceConfigImpl implements WorkspaceConfig {
workspaceConfig.getCommands(),
workspaceConfig.getProjects(),
workspaceConfig.getEnvironments(),
workspaceConfig.getAttributes());
workspaceConfig.getAttributes(),
workspaceConfig.getDevfile());
}
@Override
@ -205,6 +228,17 @@ public class WorkspaceConfigImpl implements WorkspaceConfig {
this.attributes = attributes;
}
public WorkspaceConfigImpl setDevfile(DevfileImpl devfile) {
this.devfile = devfile;
return this;
}
@Nullable
@Override
public DevfileImpl getDevfile() {
return devfile;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
@ -218,6 +252,7 @@ public class WorkspaceConfigImpl implements WorkspaceConfig {
&& Objects.equals(name, that.name)
&& Objects.equals(description, that.description)
&& Objects.equals(defaultEnv, that.defaultEnv)
&& Objects.equals(devfile, that.devfile)
&& getCommands().equals(that.getCommands())
&& getProjects().equals(that.getProjects())
&& getEnvironments().equals(that.getEnvironments())
@ -231,6 +266,7 @@ public class WorkspaceConfigImpl implements WorkspaceConfig {
hash = 31 * hash + Objects.hashCode(name);
hash = 31 * hash + Objects.hashCode(description);
hash = 31 * hash + Objects.hashCode(defaultEnv);
hash = 31 * hash + Objects.hashCode(devfile);
hash = 31 * hash + getCommands().hashCode();
hash = 31 * hash + getProjects().hashCode();
hash = 31 * hash + getEnvironments().hashCode();
@ -260,6 +296,8 @@ public class WorkspaceConfigImpl implements WorkspaceConfig {
+ environments
+ ", attributes="
+ attributes
+ ", devfile="
+ devfile
+ '}';
}

View File

@ -500,7 +500,7 @@ public class ComponentImpl implements Component {
+ "id='"
+ componentId
+ '\''
+ "alias='"
+ ", alias='"
+ alias
+ '\''
+ ", type='"

View File

@ -23,6 +23,7 @@ import org.eclipse.che.api.core.model.workspace.WorkspaceConfig;
import org.eclipse.che.api.core.model.workspace.config.Command;
import org.eclipse.che.api.core.model.workspace.config.Environment;
import org.eclipse.che.api.workspace.server.model.impl.CommandImpl;
import org.eclipse.che.api.workspace.server.model.impl.devfile.DevfileImpl;
import org.eclipse.che.api.workspace.server.spi.RuntimeInfrastructure;
import org.eclipse.che.commons.annotation.Nullable;
@ -44,6 +45,7 @@ public abstract class InternalEnvironment {
private final List<Warning> warnings;
private Map<String, String> attributes;
private List<CommandImpl> commands;
private DevfileImpl devfile;
protected InternalEnvironment() {
this.warnings = new CopyOnWriteArrayList<>();
@ -67,6 +69,7 @@ public abstract class InternalEnvironment {
this.warnings = new CopyOnWriteArrayList<>(internalEnvironment.getWarnings());
this.attributes = internalEnvironment.getAttributes();
this.commands = internalEnvironment.getCommands();
this.devfile = internalEnvironment.getDevfile();
}
/**
@ -180,4 +183,13 @@ public abstract class InternalEnvironment {
}
return this;
}
/** Return the devfile that was used for the environment constructing. */
public DevfileImpl getDevfile() {
return devfile;
}
public void setDevfile(DevfileImpl devfile) {
this.devfile = devfile;
}
}

View File

@ -96,7 +96,6 @@ public abstract class InternalEnvironmentFactory<T extends InternalEnvironment>
machines.put(
machineEntry.getKey(),
new InternalMachineConfig(
installers,
normalizeServers(machineConfig.getServers()),
machineConfig.getEnv(),
machineConfig.getAttributes(),

View File

@ -11,13 +11,10 @@
*/
package org.eclipse.che.api.workspace.server.spi.environment;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.che.api.core.model.workspace.config.ServerConfig;
import org.eclipse.che.api.core.model.workspace.config.Volume;
import org.eclipse.che.api.installer.shared.model.Installer;
/**
* Machine Config to use inside infrastructure.
@ -32,7 +29,6 @@ import org.eclipse.che.api.installer.shared.model.Installer;
* @author gazarenkov
*/
public class InternalMachineConfig {
private final List<Installer> installers;
private final Map<String, ServerConfig> servers;
private final Map<String, String> env;
private final Map<String, String> attributes;
@ -40,14 +36,12 @@ public class InternalMachineConfig {
public InternalMachineConfig() {
this.servers = new HashMap<>();
this.installers = new ArrayList<>();
this.env = new HashMap<>();
this.attributes = new HashMap<>();
this.volumes = new HashMap<>();
}
public InternalMachineConfig(
List<Installer> installers,
Map<String, ? extends ServerConfig> servers,
Map<String, String> env,
Map<String, String> attributes,
@ -67,11 +61,6 @@ public class InternalMachineConfig {
}
}
/** Returns modifiable ordered list of installers configs of the machine. */
public List<Installer> getInstallers() {
return installers;
}
/** Returns modifiable map of servers configured in the machine. */
public Map<String, ServerConfig> getServers() {
return servers;

View File

@ -549,7 +549,7 @@ public class WorkspaceManagerTest {
EnvironmentImpl environment = new EnvironmentImpl(null, emptyMap());
Command command = new CommandImpl("cmd", "echo hello", "custom");
WorkspaceConfig convertedConfig =
WorkspaceConfigImpl convertedConfig =
new WorkspaceConfigImpl(
"any",
"",
@ -575,7 +575,7 @@ public class WorkspaceManagerTest {
EnvironmentImpl environment = new EnvironmentImpl(null, emptyMap());
Command command = new CommandImpl("cmd", "echo hello", "custom");
WorkspaceConfig convertedConfig =
WorkspaceConfigImpl convertedConfig =
new WorkspaceConfigImpl(
"any",
"",
@ -615,7 +615,7 @@ public class WorkspaceManagerTest {
EnvironmentImpl environment = new EnvironmentImpl(null, emptyMap());
Command command = new CommandImpl("cmd", "echo hello", "custom");
WorkspaceConfig convertedConfig =
WorkspaceConfigImpl convertedConfig =
new WorkspaceConfigImpl(
"any",
"",

View File

@ -216,7 +216,7 @@ public class WorkspaceRuntimesTest {
when(noEnvFactory.create(eq(null))).thenReturn(expectedEnvironment);
InternalEnvironment actualEnvironment =
runtimes.createInternalEnvironment(null, emptyMap(), emptyList());
runtimes.createInternalEnvironment(null, emptyMap(), emptyList(), null);
assertEquals(actualEnvironment, expectedEnvironment);
}
@ -229,7 +229,7 @@ public class WorkspaceRuntimesTest {
throws Exception {
EnvironmentImpl environment = new EnvironmentImpl();
environment.setRecipe(new RecipeImpl("not-supported-type", "", "", null));
runtimes.createInternalEnvironment(environment, emptyMap(), emptyList());
runtimes.createInternalEnvironment(environment, emptyMap(), emptyList(), null);
}
@Test(
@ -241,7 +241,7 @@ public class WorkspaceRuntimesTest {
public void
internalEnvironmentShouldThrowExceptionWhenNoEnvironmentFactoryFoundForNoEnvironmentWorkspaceCase()
throws Exception {
runtimes.createInternalEnvironment(null, emptyMap(), emptyList());
runtimes.createInternalEnvironment(null, emptyMap(), emptyList(), null);
}
@Test

View File

@ -11,12 +11,9 @@
*/
package org.eclipse.che.api.workspace.server.devfile.convert.component.editor;
import static java.lang.String.format;
import static org.eclipse.che.api.core.model.workspace.config.Command.PLUGIN_ATTRIBUTE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.COMPONENT_ALIAS_COMMAND_ATTRIBUTE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.EDITOR_COMPONENT_ALIAS_WORKSPACE_ATTRIBUTE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.EDITOR_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.shared.Constants.SIDECAR_MEMORY_LIMIT_ATTR_TEMPLATE;
import static org.eclipse.che.api.workspace.shared.Constants.WORKSPACE_TOOLING_EDITOR_ATTRIBUTE;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.when;
@ -66,14 +63,6 @@ public class EditorComponentToWorkspaceApplierTest {
// then
assertEquals(workspaceConfig.getAttributes().get(WORKSPACE_TOOLING_EDITOR_ATTRIBUTE), editorId);
assertEquals(
workspaceConfig.getAttributes().get(EDITOR_COMPONENT_ALIAS_WORKSPACE_ATTRIBUTE),
editorId + "=" + editorComponent.getAlias());
assertEquals(
workspaceConfig
.getAttributes()
.get(format(SIDECAR_MEMORY_LIMIT_ATTR_TEMPLATE, "eclipse/super-editor")),
"12345M");
}
@Test
@ -98,18 +87,6 @@ public class EditorComponentToWorkspaceApplierTest {
assertEquals(
workspaceConfig.getAttributes().get(WORKSPACE_TOOLING_EDITOR_ATTRIBUTE),
registryUrl + "#" + editorId);
assertEquals(
workspaceConfig.getAttributes().get(EDITOR_COMPONENT_ALIAS_WORKSPACE_ATTRIBUTE),
registryUrl.substring(0, registryUrl.length() - 1)
+ "#"
+ editorId
+ "="
+ editorComponent.getAlias());
assertEquals(
workspaceConfig
.getAttributes()
.get(format(SIDECAR_MEMORY_LIMIT_ATTR_TEMPLATE, "eclipse/super-editor")),
"12345M");
}
@Test
@ -137,14 +114,7 @@ public class EditorComponentToWorkspaceApplierTest {
// then
assertEquals(
workspaceConfig.getAttributes().get(WORKSPACE_TOOLING_EDITOR_ATTRIBUTE), reference);
assertEquals(
workspaceConfig.getAttributes().get(EDITOR_COMPONENT_ALIAS_WORKSPACE_ATTRIBUTE),
"eclipse/super-editor/0.0.1" + "=" + editorComponent.getAlias());
assertEquals(
workspaceConfig
.getAttributes()
.get(format(SIDECAR_MEMORY_LIMIT_ATTR_TEMPLATE, "eclipse/super-editor")),
"12345M");
assertEquals(editorComponent.getId(), "eclipse/super-editor/0.0.1");
}
@Test

View File

@ -11,12 +11,9 @@
*/
package org.eclipse.che.api.workspace.server.devfile.convert.component.plugin;
import static java.lang.String.format;
import static org.eclipse.che.api.core.model.workspace.config.Command.PLUGIN_ATTRIBUTE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.COMPONENT_ALIAS_COMMAND_ATTRIBUTE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.PLUGINS_COMPONENTS_ALIASES_WORKSPACE_ATTRIBUTE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.PLUGIN_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.shared.Constants.SIDECAR_MEMORY_LIMIT_ATTR_TEMPLATE;
import static org.eclipse.che.api.workspace.shared.Constants.WORKSPACE_TOOLING_PLUGINS_ATTRIBUTE;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.when;
@ -80,16 +77,6 @@ public class PluginComponentToWorkspaceApplierTest {
assertTrue(workspaceTooling.matches("(.+/.+/.+),(.+/.+/.+)"));
assertTrue(workspaceTooling.contains(superPluginId));
assertTrue(workspaceTooling.contains("publisher1/custom-plugin/v1"));
String toolingAliases =
workspaceConfig.getAttributes().get(PLUGINS_COMPONENTS_ALIASES_WORKSPACE_ATTRIBUTE);
assertTrue(toolingAliases.matches("(.+/.+/.+=.+),(.+/.+/.+=.+)"));
assertTrue(toolingAliases.contains(superPluginId + "=super-plugin"));
assertTrue(toolingAliases.contains("publisher1/custom-plugin/v1=custom"));
assertEquals(
workspaceConfig
.getAttributes()
.get(format(SIDECAR_MEMORY_LIMIT_ATTR_TEMPLATE, "eclipse/super-plugin")),
"1234M");
}
@Test
@ -124,16 +111,6 @@ public class PluginComponentToWorkspaceApplierTest {
assertTrue(workspaceTooling.matches("(.+/.+/.+),(.+/.+/.+)"));
assertTrue(workspaceTooling.contains(superPluginId));
assertTrue(workspaceTooling.contains(registryUrl + "#" + "publisher1/custom-plugin/v1"));
String toolingAliases =
workspaceConfig.getAttributes().get(PLUGINS_COMPONENTS_ALIASES_WORKSPACE_ATTRIBUTE);
assertTrue(toolingAliases.matches("(.+/.+/.+=.+),(.+/.+/.+=.+)"));
assertTrue(toolingAliases.contains(superPluginId + "=super-plugin"));
assertTrue(toolingAliases.contains("publisher1/custom-plugin/v1=custom"));
assertEquals(
workspaceConfig
.getAttributes()
.get(format(SIDECAR_MEMORY_LIMIT_ATTR_TEMPLATE, "eclipse/super-plugin")),
"1234M");
}
@Test
@ -174,11 +151,7 @@ public class PluginComponentToWorkspaceApplierTest {
assertTrue(workspaceTooling.matches("(.+/.+/.+),(https://.+/.+/.+)"));
assertTrue(workspaceTooling.contains(superPluginId));
assertTrue(workspaceTooling.contains(reference));
assertEquals(
workspaceConfig
.getAttributes()
.get(format(SIDECAR_MEMORY_LIMIT_ATTR_TEMPLATE, "eclipse/super-plugin")),
"1234M");
assertEquals(customPluginComponent.getId(), "eclipse/super-plugin/0.0.1");
}
@Test

View File

@ -11,7 +11,6 @@
*/
package org.eclipse.che.api.workspace.server.spi.environment;
import static java.util.Collections.emptyList;
import static java.util.Collections.emptyMap;
import static java.util.Collections.singletonMap;
import static org.eclipse.che.api.core.model.workspace.config.MachineConfig.MEMORY_LIMIT_ATTRIBUTE;
@ -212,7 +211,6 @@ public class MachineConfigsValidatorTest {
private static InternalMachineConfig machineMock() {
InternalMachineConfig machineConfig = mock(InternalMachineConfig.class);
when(machineConfig.getServers()).thenReturn(emptyMap());
when(machineConfig.getInstallers()).thenReturn(emptyList());
return machineConfig;
}