Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,13 @@
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
* Build service for detecting available Docker installation and checking for compatibility with OpenSearch Docker image build
Expand All @@ -66,16 +68,24 @@
public abstract class DockerSupportService implements BuildService<DockerSupportService.Parameters> {

private static Logger LOGGER = Logging.getLogger(DockerSupportService.class);

private static String[] DEFAULT_PATH_UNIX = { "/usr/bin", "/usr/local/bin" };

// Get unix path from PATH env variable, with fallback to DEFAUL_PATH_UNIX
private static String[] PATH_UNIX = DockerSupportService.getUnixPath(System.getenv("PATH"), DEFAULT_PATH_UNIX);

// Defines the possible locations of the Docker CLI. These will be searched in order.
private static String[] DOCKER_BINARIES_UNIX = { "/usr/bin/docker", "/usr/local/bin/docker" };
private static String[] DOCKER_BINARIES_UNIX = Arrays.stream(PATH_UNIX).map((String path) -> path + "/docker").toArray(String[]::new);

private static String[] DOCKER_BINARIES_WINDOWS = {
System.getenv("PROGRAMFILES") + "\\Docker\\Docker\\resources\\bin\\docker.exe",
System.getenv("SystemRoot") + "\\System32\\docker.exe" /* Github Actions */ };

private static String[] DOCKER_BINARIES = Os.isFamily(Os.FAMILY_WINDOWS) ? DOCKER_BINARIES_WINDOWS : DOCKER_BINARIES_UNIX;

private static String[] DOCKER_COMPOSE_BINARIES_UNIX = { "/usr/local/bin/docker-compose", "/usr/bin/docker-compose" };
private static String[] DOCKER_COMPOSE_BINARIES_UNIX = Arrays.stream(PATH_UNIX)
.map((String path) -> path + "/docker-compose")
.toArray(String[]::new);

private static String[] DOCKER_COMPOSE_BINARIES_WINDOWS = {
System.getenv("PROGRAMFILES") + "\\Docker\\Docker\\resources\\bin\\docker-compose.exe" };
Expand Down Expand Up @@ -289,6 +299,27 @@ static Map<String, String> parseOsRelease(final List<String> osReleaseLines) {
return values;
}

/**
* Visible for testing
*
* If the system is of Unix family it converts the PATH string to array, combines it with fallback
* path removing duplicates and returns it as array.
*
* @return an array containing PATH locations
*/
static String[] getUnixPath(String pathEnvString, String[] fallbackPath) {
if (!Os.isFamily(Os.FAMILY_WINDOWS) && pathEnvString instanceof String) {
String[] resolvedUnixPath = pathEnvString.split(":");
Stream<String> filteredUnixPath = Arrays.stream(resolvedUnixPath).filter(path -> path.length() > 0);
return Stream.concat(filteredUnixPath, Arrays.stream(fallbackPath))
// LinkedHashSet removes duplicates and keeps the order
.collect(Collectors.toCollection(LinkedHashSet::new))
.toArray(String[]::new);
}

return fallbackPath;
}

/**
* Searches the entries in {@link #DOCKER_BINARIES} for the Docker CLI. This method does
* not check whether the Docker installation appears usable, see {@link #getDockerAvailability()}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import java.util.Map;

import static org.opensearch.gradle.docker.DockerSupportService.deriveId;
import static org.opensearch.gradle.docker.DockerSupportService.getUnixPath;
import static org.opensearch.gradle.docker.DockerSupportService.parseOsRelease;
import static org.hamcrest.CoreMatchers.equalTo;

Expand Down Expand Up @@ -123,4 +124,32 @@ public void testDeriveIdOnOracle() {

assertThat("ol-6.10", equalTo(deriveId(osRelease)));
}

public void testGetUnixPathDefault() {
final String[] fallbackPath = { "/usr/bin", "/usr/local/bin" };
final String path = null;

assertArrayEquals(fallbackPath, getUnixPath(path, fallbackPath));
}

public void testGetUnixPathEmptyString() {
final String[] fallbackPath = { "/usr/bin", "/usr/local/bin" };
final String path = "";

assertArrayEquals(fallbackPath, getUnixPath(path, fallbackPath));
}

/**
* Tests:
* 1. Duplicates are removed.
* 2. The order is preserved, prioritizing the order from path over the order from fallback.
*/
public void testGetUnixPathWithDuplicatesAndEmptyEntries() {
final String[] fallbackPath = { "/usr/bin", "/usr/local/bin" };
final String path = "/home/User/bin:/usr/local/bin:/bin::/home/User/bin";

final String[] expected = { "/home/User/bin", "/usr/local/bin", "/bin", "/usr/bin" };

assertArrayEquals(expected, getUnixPath(path, fallbackPath));
}
}
Loading