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 Feb 25, 2019
1 parent c19e664 commit 759f38f
Show file tree
Hide file tree
Showing 5 changed files with 136 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.dataformat.yaml.YAMLMapper;
import java.io.IOException;
Expand Down Expand Up @@ -88,6 +89,21 @@ public EntryPoint parse(Map<String, String> machineAttributes) throws Infrastruc
}
}

/**
* 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 @@ -76,14 +76,23 @@ public void shouldAcceptYAMLString() {
}

@Test
public void shouldAcceptYAMLList() {
public void shouldAcceptYAMLJSONList() {
EntryPointParser parser = new EntryPointParser();

List<String> parsed = parser.parseEntry("[--yes, -b, '''c']");

assertEquals(asList("--yes", "-b", "'c"), parsed);
}

@Test
public void shouldAcceptYAMLList() {
EntryPointParser parser = new EntryPointParser();

List<String> parsed = parser.parseEntry("- \"--yes\"\n- '-b'\n- '''c'");

assertEquals(asList("--yes", "-b", "'c"), parsed);
}

@Test(dataProvider = "invalidEntryProvider")
public void shouldFailOnOtherYAMLDataType(String invalidEntry) {
EntryPointParser parser = new EntryPointParser();
Expand All @@ -100,4 +109,22 @@ public static Object[][] invalidEntryProvider() {
new String[] {"[a, b, 1]"}
};
}

@Test(dataProvider = "dataToSerialize")
public void shouldSerializeValidData(List<String> data, String expectedSerialization) {
EntryPointParser parser = new EntryPointParser();

String serialized = parser.serializeEntry(data);

assertEquals(expectedSerialization, serialized);
}

@DataProvider
public static Object[][] dataToSerialize() {
return new Object[][] {
// these are dependent on the configuration of the YAML generator used by the YAMLMapper
// so these might start failing on jackson-dataformat-yaml library upgrade
new Object[] {asList("/bin/sh", "-c"), "---\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.docker.environment.dockerimage.EntryPoint;
import org.eclipse.che.workspace.infrastructure.docker.environment.dockerimage.EntryPointParser;

/**
* Provision dockerimage tool in {@link Devfile} according to the value of environment with
Expand Down Expand Up @@ -117,6 +121,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 @@ -127,6 +135,15 @@ public void provision(Devfile devfile, WorkspaceConfigImpl workspaceConfig)
devfile.getTools().add(dockerimageTool);
}

private EntryPoint toEntryPoint(MachineConfig machineConfig) throws WorkspaceExportException {
try {
EntryPointParser entryPointParser = new EntryPointParser();
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,16 @@
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.Collections;
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 +39,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.docker.environment.dockerimage.EntryPointParser;
import org.eclipse.che.workspace.infrastructure.kubernetes.util.KubernetesSize;

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

EntryPointParser parser = new EntryPointParser();
setEntryPointAttribute(
parser, machineConfig, CONTAINER_COMMAND_ATTRIBUTE, dockerimageTool.getCommand());
setEntryPointAttribute(
parser, machineConfig, CONTAINER_ARGS_ATTRIBUTE, dockerimageTool.getArgs());

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

@SuppressWarnings("unchecked")
private static void setEntryPointAttribute(
EntryPointParser parser,
MachineConfigImpl machineConfig,
String attributeName,
Object attributeValue) {
if (attributeValue == null) {
return;
}

List<String> attr;
if (attributeValue instanceof String) {
attr = Collections.singletonList((String) attributeValue);
} else {
attr = (List<String>) attributeValue;
}

String val = parser.serializeEntry(attr);

machineConfig.getAttributes().put(attributeName, val);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,48 @@
"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": {
"oneOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"type": "string"
}
],
"description": "The command to run in the dockerimage tool instead of the default one provided in the image.",
"examples": [
[
"/bin/sh",
"-c"
],
"/startup.sh"
]
},
"args": {
"oneOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"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"
],
"--force"
]
},
"volumes": {
"type": "array",
"description": "Describes volumes which should be mount to tool",
Expand Down

0 comments on commit 759f38f

Please sign in to comment.