Skip to content

Commit

Permalink
Add command/arg support to dockerimage tool in devfile
Browse files Browse the repository at this point in the history
Signed-off-by: Lukas Krejci <lkrejci@redhat.com>
  • Loading branch information
metlos committed Mar 5, 2019
1 parent 1dc5b8b commit e22f869
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import static java.lang.String.format;
import static java.util.Collections.emptyList;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.dataformat.yaml.YAMLMapper;
import java.io.IOException;
Expand Down Expand Up @@ -52,6 +53,21 @@ public EntryPoint parse(Map<String, String> machineAttributes) throws Infrastruc
return new EntryPoint(commandList, argList);
}

/**
* Serializes an entry (that might have been produced from {@link #parse(Map)}) back to a string
* representation.
*
* @param entry the command or args entry
* @return a serialized representation of the entry
*/
public String serializeEntry(List<String> entry) {
try {
return mapper.writer().writeValueAsString(entry);
} catch (JsonProcessingException e) {
throw new IllegalArgumentException(e);
}
}

private List<String> parseAsList(String data, String attributeName)
throws InfrastructureException {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import static org.testng.AssertJUnit.assertEquals;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.che.api.core.model.workspace.config.MachineConfig;
import org.eclipse.che.api.workspace.server.spi.InfrastructureException;
Expand Down Expand Up @@ -83,4 +84,21 @@ public static Object[][] invalidEntryProvider() {
new String[] {"[a, b, [c]]"}
};
}

@Test
public void shouldSerializeValidData() {
// given
List<String> data = asList("/bin/sh", "-c");

EntryPointParser parser = new EntryPointParser();

// when
String serialized = parser.serializeEntry(data);

// then

// this is dependent on the configuration of the YAML generator used by the YAMLMapper used in
// the EntryPointParser so this may start failing on jackson-dataformat-yaml library upgrade
assertEquals(serialized, "---\n- \"/bin/sh\"\n- \"-c\"\n");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import org.eclipse.che.api.core.model.workspace.config.MachineConfig;
import org.eclipse.che.api.devfile.model.Devfile;
import org.eclipse.che.api.devfile.model.Endpoint;
import org.eclipse.che.api.devfile.model.Env;
Expand All @@ -34,7 +35,10 @@
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.spi.InfrastructureException;
import org.eclipse.che.workspace.infrastructure.docker.environment.dockerimage.DockerImageEnvironment;
import org.eclipse.che.workspace.infrastructure.kubernetes.environment.util.EntryPoint;
import org.eclipse.che.workspace.infrastructure.kubernetes.environment.util.EntryPointParser;

/**
* Provision dockerimage tool in {@link Devfile} according to the value of environment with
Expand All @@ -44,6 +48,8 @@
*/
public class DockerimageToolProvisioner implements ToolProvisioner {

private final EntryPointParser entryPointParser = new EntryPointParser();

/**
* Provision dockerimage tool in {@link Devfile} according to the value of environment with
* dockerimage recipe if the specified {@link WorkspaceConfigImpl} has such.
Expand Down Expand Up @@ -118,6 +124,10 @@ public void provision(Devfile devfile, WorkspaceConfigImpl workspaceConfig)

dockerimageTool.setMemoryLimit(machineConfig.getAttributes().get(MEMORY_LIMIT_ATTRIBUTE));

EntryPoint ep = toEntryPoint(machineConfig);
dockerimageTool.setCommand(ep.getCommand());
dockerimageTool.setArgs(ep.getArguments());

machineConfig
.getEnv()
.entrySet()
Expand All @@ -128,6 +138,14 @@ public void provision(Devfile devfile, WorkspaceConfigImpl workspaceConfig)
devfile.getTools().add(dockerimageTool);
}

private EntryPoint toEntryPoint(MachineConfig machineConfig) throws WorkspaceExportException {
try {
return entryPointParser.parse(machineConfig.getAttributes());
} catch (InfrastructureException e) {
throw new WorkspaceExportException(e.getMessage());
}
}

private Volume toDevfileVolume(String name, VolumeImpl volume) {
return new Volume().withName(name).withContainerPath(volume.getPath());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,15 @@
import static com.google.common.base.Strings.isNullOrEmpty;
import static java.lang.String.format;
import static org.eclipse.che.api.core.model.workspace.config.Command.MACHINE_NAME_ATTRIBUTE;
import static org.eclipse.che.api.core.model.workspace.config.MachineConfig.CONTAINER_ARGS_ATTRIBUTE;
import static org.eclipse.che.api.core.model.workspace.config.MachineConfig.CONTAINER_COMMAND_ATTRIBUTE;
import static org.eclipse.che.api.core.model.workspace.config.MachineConfig.MEMORY_LIMIT_ATTRIBUTE;
import static org.eclipse.che.api.devfile.server.Constants.DOCKERIMAGE_TOOL_TYPE;
import static org.eclipse.che.api.workspace.shared.Constants.PROJECTS_VOLUME_NAME;

import com.google.common.collect.ImmutableMap;
import java.util.HashMap;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Named;
import org.eclipse.che.api.devfile.model.Endpoint;
Expand All @@ -35,6 +38,7 @@
import org.eclipse.che.api.workspace.server.model.impl.VolumeImpl;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
import org.eclipse.che.workspace.infrastructure.docker.environment.dockerimage.DockerImageEnvironment;
import org.eclipse.che.workspace.infrastructure.kubernetes.environment.util.EntryPointParser;
import org.eclipse.che.workspace.infrastructure.kubernetes.util.KubernetesSize;

/**
Expand All @@ -45,6 +49,7 @@
public class DockerimageToolToWorkspaceApplier implements ToolToWorkspaceApplier {

private final String projectFolderPath;
private final EntryPointParser entryPointParser = new EntryPointParser();

@Inject
public DockerimageToolToWorkspaceApplier(
Expand Down Expand Up @@ -116,6 +121,10 @@ public void apply(
MEMORY_LIMIT_ATTRIBUTE,
Long.toString(KubernetesSize.toBytes(dockerimageTool.getMemoryLimit())));

setEntryPointAttribute(
machineConfig, CONTAINER_COMMAND_ATTRIBUTE, dockerimageTool.getCommand());
setEntryPointAttribute(machineConfig, CONTAINER_ARGS_ATTRIBUTE, dockerimageTool.getArgs());

RecipeImpl recipe =
new RecipeImpl(DockerImageEnvironment.TYPE, null, dockerimageTool.getImage(), null);
EnvironmentImpl environment =
Expand All @@ -133,4 +142,16 @@ public void apply(
.equals(c.getAttributes().get(Constants.TOOL_NAME_COMMAND_ATTRIBUTE)))
.forEach(c -> c.getAttributes().put(MACHINE_NAME_ATTRIBUTE, machineName));
}

private void setEntryPointAttribute(
MachineConfigImpl machineConfig, String attributeName, List<String> attributeValue) {

if (attributeValue == null) {
return;
}

String val = entryPointParser.serializeEntry(attributeValue);

machineConfig.getAttributes().put(attributeName, val);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,32 @@
"description": "Describes whether projects sources should be mount to the tool. `CHE_PROJECTS_ROOT` environment variable should contains a path where projects sources are mount",
"default": "false"
},
"command": {
"type": "array",
"items": {
"type": "string"
},
"description": "The command to run in the dockerimage tool instead of the default one provided in the image.",
"examples": [
[
"/bin/sh",
"-c"
]
]
},
"args": {
"type": "array",
"items": {
"type": "string"
},
"description": "The arguments to supply to the command running the dockerimage tool. The arguments are supplied either to the default command provided in the image or to the overridden command.",
"examples": [
[
"-R",
"-f"
]
]
},
"volumes": {
"type": "array",
"description": "Describes volumes which should be mount to tool",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,17 @@

import static java.util.Collections.emptyMap;
import static java.util.Collections.singletonList;
import static org.eclipse.che.api.core.model.workspace.config.MachineConfig.CONTAINER_ARGS_ATTRIBUTE;
import static org.eclipse.che.api.core.model.workspace.config.MachineConfig.CONTAINER_COMMAND_ATTRIBUTE;
import static org.eclipse.che.api.core.model.workspace.config.MachineConfig.MEMORY_LIMIT_ATTRIBUTE;
import static org.eclipse.che.api.devfile.server.Constants.DOCKERIMAGE_TOOL_TYPE;
import static org.eclipse.che.api.workspace.shared.Constants.PROJECTS_VOLUME_NAME;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;

import com.google.common.collect.ImmutableMap;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import org.eclipse.che.api.devfile.model.Endpoint;
import org.eclipse.che.api.devfile.model.Env;
Expand All @@ -31,6 +35,7 @@
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.workspace.infrastructure.kubernetes.environment.util.EntryPointParser;
import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
Expand Down Expand Up @@ -244,6 +249,35 @@ public void shouldProvisionMachineConfigWithoutSourcesByDefault() throws Excepti
Assert.assertFalse(machineConfig.getVolumes().containsKey(PROJECTS_VOLUME_NAME));
}

@Test
public void shouldProvisionCommandAndArgs() throws Exception {
// given
List<String> command = singletonList("/usr/bin/rf");
List<String> args = Arrays.asList("-r", "f");

Tool dockerimageTool =
new Tool()
.withName("jdk")
.withType(DOCKERIMAGE_TOOL_TYPE)
.withImage("eclipse/ubuntu_jdk8:latest")
.withMemoryLimit("1G")
.withCommand(command)
.withArgs(args);

EntryPointParser parser = new EntryPointParser();

// when
dockerimageToolApplier.apply(workspaceConfig, dockerimageTool, null);

// then
MachineConfigImpl machineConfig = getMachineConfig(workspaceConfig, "jdk");
Assert.assertEquals(
machineConfig.getAttributes().get(CONTAINER_COMMAND_ATTRIBUTE),
parser.serializeEntry(command));
Assert.assertEquals(
machineConfig.getAttributes().get(CONTAINER_ARGS_ATTRIBUTE), parser.serializeEntry(args));
}

private MachineConfigImpl getMachineConfig(
WorkspaceConfigImpl workspaceConfig, String machineName) {
String defaultEnvName = workspaceConfig.getDefaultEnv();
Expand Down

0 comments on commit e22f869

Please sign in to comment.