Search in sources :

Example 1 with Feature

use of com.oracle.bedrock.extensible.Feature in project oracle-bedrock by coherence-community.

the class DockerRemoteTerminal method runContainer.

/**
 * Run a container using the specified image.
 *
 * @param containerName  the name of the container
 * @param launchable     the {@link RemoteTerminal.Launchable} that will give the command to execute
 * @param image          the image to use to run the container
 * @param docker         the {@link Docker} environment to use
 * @param optionsByType  the {@link OptionsByType} to use
 *
 * @return  a {@link DockerContainer} representing the running image
 */
protected ApplicationProcess runContainer(String containerName, Launchable launchable, DockerImage image, Docker docker, OptionsByType optionsByType) {
    Timeout timeout = optionsByType.get(Timeout.class);
    WorkingDirectory workingDirectory = optionsByType.get(WorkingDirectory.class);
    String workingDirectoryName = workingDirectory.resolve(platform, optionsByType).toString();
    optionsByType.add(PlatformSeparators.forUnix());
    optionsByType.add(new CPModifier(workingDirectoryName));
    // ----- give the container a random UUID as a name -----
    DisplayName displayName = optionsByType.getOrSetDefault(DisplayName.class, DisplayName.of("Container"));
    // ----- create the arguments to pass to the container as the command to execute
    String command = launchable.getCommandToExecute(platform, optionsByType);
    List<?> args = launchable.getCommandLineArguments(platform, optionsByType);
    Arguments containerArgs = Arguments.of(command).with(args);
    // ----- get any captured ports to map -----
    Ports ports = optionsByType.get(Ports.class);
    List<Integer> portList = ports.getPorts().stream().map(Ports.Port::getActualPort).collect(Collectors.toList());
    // ----- create the Run command -----
    Run runCommand = Run.image(image, containerName).interactive().net(docker.getDefaultNetworkName()).hostName(containerName).env(launchable.getEnvironmentVariables(platform, optionsByType)).publish(portList).autoRemove();
    OptionsByType containerOptions = OptionsByType.of(optionsByType).addAll(displayName, docker, WorkingDirectory.at(tmpFolder), ContainerCloseBehaviour.none(), ImageCloseBehaviour.remove(), containerArgs);
    // ----- start the application to capture Docker events so that we know when the container is in the running state -----
    EventsApplicationConsole.CountDownListener latch = new EventsApplicationConsole.CountDownListener(1);
    Predicate<String> predicate = (line) -> line.contains("container start");
    EventsApplicationConsole eventConsole = new EventsApplicationConsole().withStdOutListener(predicate, latch);
    try (Application events = platform.launch(Events.fromContainer(containerName), docker, Console.of(eventConsole))) {
        // ----- launch the container -----
        ContainerApplication application = platform.launch(new ContainerMetaClass(runCommand), containerOptions.asArray());
        // ----- get the container feature from the application -----
        DockerContainer container = application.get(DockerContainer.class);
        FeatureAddingProfile profile = new FeatureAddingProfile(image, container);
        // ----- add the container and default close behaviour to the options
        optionsByType.add(profile);
        optionsByType.add(ImageCloseBehaviour.remove());
        try {
            if (!latch.await(timeout.to(TimeUnit.MILLISECONDS), TimeUnit.MILLISECONDS)) {
                throw new RuntimeException("Failed to detect container start event within " + timeout);
            }
        } catch (InterruptedException e) {
        // ignored
        }
        // ----- obtain the port mappings from the container -----
        JsonObject jsonNet = (JsonObject) container.inspect("{{json .NetworkSettings}}");
        if (!jsonNet.get("Ports").getValueType().equals(JsonValue.ValueType.NULL)) {
            JsonObject jsonPorts = jsonNet.getJsonObject("Ports");
            List<Ports.Port> mappedPorts = ports.getPorts().stream().map((port) -> {
                String key = port.getActualPort() + "/tcp";
                String hostPort = jsonPorts.getJsonArray(key).getJsonObject(0).getString("HostPort");
                return new Ports.Port(port.getName(), port.getActualPort(), Integer.parseInt(hostPort));
            }).collect(Collectors.toList());
            // ----- update the options with the correctly mapped ports -----
            optionsByType.remove(Ports.class);
            optionsByType.add(Ports.of(mappedPorts));
        }
        // ----- return the process from the container application -----
        return application.getProcess();
    }
}
Also used : NullApplicationConsole(com.oracle.bedrock.runtime.console.NullApplicationConsole) Arrays(java.util.Arrays) Timeout(com.oracle.bedrock.options.Timeout) ImageCloseBehaviour(com.oracle.bedrock.runtime.docker.options.ImageCloseBehaviour) RemoteTerminal(com.oracle.bedrock.runtime.remote.RemoteTerminal) Discriminator(com.oracle.bedrock.runtime.options.Discriminator) JsonValue(javax.json.JsonValue) InetAddress(java.net.InetAddress) Console(com.oracle.bedrock.runtime.options.Console) Deployer(com.oracle.bedrock.runtime.remote.options.Deployer) AbstractExtensible(com.oracle.bedrock.extensible.AbstractExtensible) OptionsByType(com.oracle.bedrock.OptionsByType) Build(com.oracle.bedrock.runtime.docker.commands.Build) StringHelper(com.oracle.bedrock.lang.StringHelper) PrintWriter(java.io.PrintWriter) Bedrock(com.oracle.bedrock.Bedrock) Events(com.oracle.bedrock.runtime.docker.commands.Events) JsonObject(javax.json.JsonObject) Predicate(java.util.function.Predicate) ContainerCloseBehaviour(com.oracle.bedrock.runtime.docker.options.ContainerCloseBehaviour) UUID(java.util.UUID) EventsApplicationConsole(com.oracle.bedrock.runtime.console.EventsApplicationConsole) Logger(java.util.logging.Logger) Collectors(java.util.stream.Collectors) Option(com.oracle.bedrock.Option) List(java.util.List) Feature(com.oracle.bedrock.extensible.Feature) Platform(com.oracle.bedrock.runtime.Platform) Run(com.oracle.bedrock.runtime.docker.commands.Run) DeployedArtifacts(com.oracle.bedrock.runtime.remote.DeployedArtifacts) Remove(com.oracle.bedrock.runtime.docker.commands.Remove) ArrayList(java.util.ArrayList) Level(java.util.logging.Level) ApplicationProcess(com.oracle.bedrock.runtime.ApplicationProcess) MetaClass(com.oracle.bedrock.runtime.MetaClass) PlatformSeparators(com.oracle.bedrock.runtime.options.PlatformSeparators) Variable(com.oracle.bedrock.options.Variable) RemoteApplicationProcess(com.oracle.bedrock.runtime.remote.RemoteApplicationProcess) Kill(com.oracle.bedrock.runtime.docker.commands.Kill) Application(com.oracle.bedrock.runtime.Application) ClassPathModifier(com.oracle.bedrock.runtime.java.ClassPathModifier) OutputStream(java.io.OutputStream) Properties(java.util.Properties) WorkingDirectory(com.oracle.bedrock.runtime.options.WorkingDirectory) Files(java.nio.file.Files) IOException(java.io.IOException) Arguments(com.oracle.bedrock.runtime.options.Arguments) File(java.io.File) Table(com.oracle.bedrock.table.Table) TimeUnit(java.util.concurrent.TimeUnit) Ports(com.oracle.bedrock.runtime.options.Ports) DeploymentArtifact(com.oracle.bedrock.runtime.remote.DeploymentArtifact) DockerfileDeployer(com.oracle.bedrock.runtime.docker.options.DockerfileDeployer) DisplayName(com.oracle.bedrock.runtime.options.DisplayName) FileHelper(com.oracle.bedrock.io.FileHelper) Profile(com.oracle.bedrock.runtime.Profile) InputStream(java.io.InputStream) JsonObject(javax.json.JsonObject) DisplayName(com.oracle.bedrock.runtime.options.DisplayName) WorkingDirectory(com.oracle.bedrock.runtime.options.WorkingDirectory) Timeout(com.oracle.bedrock.options.Timeout) Arguments(com.oracle.bedrock.runtime.options.Arguments) Ports(com.oracle.bedrock.runtime.options.Ports) Run(com.oracle.bedrock.runtime.docker.commands.Run) EventsApplicationConsole(com.oracle.bedrock.runtime.console.EventsApplicationConsole) OptionsByType(com.oracle.bedrock.OptionsByType) Application(com.oracle.bedrock.runtime.Application)

Aggregations

Bedrock (com.oracle.bedrock.Bedrock)1 Option (com.oracle.bedrock.Option)1 OptionsByType (com.oracle.bedrock.OptionsByType)1 AbstractExtensible (com.oracle.bedrock.extensible.AbstractExtensible)1 Feature (com.oracle.bedrock.extensible.Feature)1 FileHelper (com.oracle.bedrock.io.FileHelper)1 StringHelper (com.oracle.bedrock.lang.StringHelper)1 Timeout (com.oracle.bedrock.options.Timeout)1 Variable (com.oracle.bedrock.options.Variable)1 Application (com.oracle.bedrock.runtime.Application)1 ApplicationProcess (com.oracle.bedrock.runtime.ApplicationProcess)1 MetaClass (com.oracle.bedrock.runtime.MetaClass)1 Platform (com.oracle.bedrock.runtime.Platform)1 Profile (com.oracle.bedrock.runtime.Profile)1 EventsApplicationConsole (com.oracle.bedrock.runtime.console.EventsApplicationConsole)1 NullApplicationConsole (com.oracle.bedrock.runtime.console.NullApplicationConsole)1 Build (com.oracle.bedrock.runtime.docker.commands.Build)1 Events (com.oracle.bedrock.runtime.docker.commands.Events)1 Kill (com.oracle.bedrock.runtime.docker.commands.Kill)1 Remove (com.oracle.bedrock.runtime.docker.commands.Remove)1