All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.arquillian.cube.docker.impl.util.DockerMachine Maven / Gradle / Ivy

package org.arquillian.cube.docker.impl.util;

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;
import java.util.regex.Pattern;

public class DockerMachine extends AbstractCliInternetAddressResolver {

    public static final String DOCKER_MACHINE_EXEC = "docker-machine";
    private static final Pattern IP_PATTERN = Pattern.compile("(?:\\d{1,3}\\.){3}\\d{1,3}");
    private static Logger log = Logger.getLogger(DockerMachine.class.getName());
    private String machineName;
    private boolean manuallyStarted = false;

    public DockerMachine(CommandLineExecutor commandLineExecutor) {
        super(commandLineExecutor);
    }

    @Override
    protected String[] getCommandArguments(String cliPathExec) {
        if (machineName == null) {
            throw new IllegalArgumentException("Machine Name cannot be null and couldn't be autoresolved.");
        }

        return new String[] {createDockerMachineCommand(cliPathExec), "ip", machineName};
    }

    @Override
    protected Pattern getIpPattern() {
        return IP_PATTERN;
    }

    public void setMachineName(String machineName) {
        this.machineName = machineName;
    }

    public boolean isManuallyStarted() {
        return manuallyStarted;
    }

    /**
     * Starts given docker machine.
     *
     * @param cliPathExec
     *     location of docker-machine or null if it is on PATH.
     * @param machineName
     *     to be started.
     */
    public void startDockerMachine(String cliPathExec, String machineName) {
        commandLineExecutor.execCommand(createDockerMachineCommand(cliPathExec), "start", machineName);
        this.manuallyStarted = true;
    }

    /**
     * Starts given docker machine.
     *
     * @param machineName
     *     to be started.
     */
    public void startDockerMachine(String machineName) {
        startDockerMachine(null, machineName);
    }

    public void stopDockerMachine(String cliPathExec, String machineName) {
        commandLineExecutor.execCommand(createDockerMachineCommand(cliPathExec), "stop", machineName);
        this.manuallyStarted = false;
    }

    public void stopDockerMachine(String machineName) {
        stopDockerMachine(null, machineName);
    }

    /**
     * Checks if Docker Machine is installed by running docker-machine and inspect the result.
     *
     * @param cliPathExec
     *     location of docker-machine or null if it is on PATH.
     *
     * @return true if it is installed, false otherwise.
     */
    public boolean isDockerMachineInstalled(String cliPathExec) {
        try {
            commandLineExecutor.execCommand(createDockerMachineCommand(cliPathExec));
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * Checks if Docker Machine is installed by running docker-machine and inspect the result.
     *
     * @return true if it is installed, false otherwise.
     */
    public boolean isDockerMachineInstalled() {
        return isDockerMachineInstalled(null);
    }

    /**
     * Executes docker-machine ls command
     *
     * @param cliPathExec
     *     location of docker-machine or null if it is on PATH.
     *
     * @return set of machines
     */
    public Set list(String cliPathExec) {

        Set machines = new HashSet<>();
        List output = commandLineExecutor.execCommandAsArray(createDockerMachineCommand(cliPathExec), "ls");

        Map headerIndex = calculateStartingFieldsIndex(output.get(0));
        for (String fields : output.subList(1, output.size())) {
            machines.add(parse(headerIndex, fields));
        }

        return machines;
    }

    /**
     * Executes docker-machine ls --filter field=value command
     *
     * @param cliPathExec
     *     location of docker-machine or null if it is on PATH.
     * @param field
     *     to use in condition
     * @param value
     *     value that the field should have
     *
     * @return set of machines
     */
    public Set list(String cliPathExec, String field, String value) {
        final Set machines = new HashSet<>();
        List output =
            commandLineExecutor.execCommandAsArray(createDockerMachineCommand(cliPathExec), "ls", "--filter",
                field + "=" + value);
        output = findHeader(output);

        if (!output.isEmpty()) {
            final Map headerIndex = calculateStartingFieldsIndex(output.get(0));
            for (String fields : output.subList(1, output.size())) {
                machines.add(parse(headerIndex, fields));
            }
        }

        return machines;
    }

    private List findHeader(List output) {
        for (int i = 0; i < output.size(); i++) {
            if (output.get(i).startsWith("NAME")) {
                return output.subList(i, output.size());
            }
        }

        return output;
    }

    private Map calculateStartingFieldsIndex(String header) {
        Map headersIndex = new HashMap<>();
        String[] headers = header.split("\\s+");
        for (int i = 0; i < headers.length; i++) {
            String currentHeader = headers[i];
            int firstIndex = header.indexOf(currentHeader);
            int lastIndex = (i + 1 < headers.length) ? header.indexOf(headers[i + 1]) - 1 : -1;

            headersIndex.put(currentHeader, new Index(firstIndex, lastIndex));
        }
        return headersIndex;
    }

    /**
     * Executes docker-machine ls command
     *
     * @return set of machines
     */
    public Set list() {
        return this.list(null);
    }

    /**
     * Executes docker-machine ls --filter field=value command
     *
     * @param field
     *     to use in condition
     * @param value
     *     value that the field shoudl have
     *
     * @return set of machines
     */
    public Set list(String field, String value) {
        return this.list(null, field, value);
    }

    public void grantPermissionToDockerMachine(String machinePath) {
        List chmod = commandLineExecutor.execCommandAsArray("chmod", "+x", machinePath);
        printOutput(chmod);
    }

    public void createMachine(String machinePath, String machineDriver, String machineName) {
        List create =
            commandLineExecutor.execCommandAsArray(machinePath, "create", "--driver", machineDriver, machineName);
        printOutput(create);
    }

    private void printOutput(List lines) {
        StringBuilder output = new StringBuilder();
        for (String line : lines) {
            output.append(line);
            output.append(System.lineSeparator());
        }
        log.info(output.toString());
    }

    private Machine parse(Map headersIndex, String output) {
        String name = resolveField(headersIndex.get("NAME"), output);
        String active = resolveField(headersIndex.get("ACTIVE"), output);
        String driver = resolveField(headersIndex.get("DRIVER"), output);
        String state = resolveField(headersIndex.get("STATE"), output);
        String url = resolveField(headersIndex.get("URL"), output);
        String swarm = resolveField(headersIndex.get("SWARM"), output);

        return new Machine(name, active, driver, state, url, swarm);
    }

    private String resolveField(Index index, String output) {
        if (index.getEndIndex() < 0) {
            if (index.getStartIndex() < 0) {
                return "";
            }
            return output.substring(index.getStartIndex(), output.length()).trim();
        } else {
            return output.substring(index.getStartIndex(), index.getEndIndex() + 1).trim();
        }
    }

    private String createDockerMachineCommand(String dockerMachinePath) {
        return dockerMachinePath == null ? DOCKER_MACHINE_EXEC : dockerMachinePath;
    }

    private class Index {
        private int startIndex = -1;
        private int endIndex = -1;

        public Index(int startIndex, int endIndex) {
            this.startIndex = startIndex;
            this.endIndex = endIndex;
        }

        public int getStartIndex() {
            return startIndex;
        }

        public int getEndIndex() {
            return endIndex;
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy