use of com.oracle.bedrock.runtime.docker.commands.Run 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();
}
}
Aggregations