public void executeCommand(String containerId, String[] command, boolean waitForExecution) { final ExecCreation execCreation; try { execCreation = dockerClient.execCreate(containerId, command, DockerClient.ExecCreateParam.attachStdout(), DockerClient.ExecCreateParam.attachStderr(), DockerClient.ExecCreateParam.attachStdin()); final LogStream output = dockerClient.execStart(execCreation.id()); logger.debug(String.format("%s %s", nodeId, Arrays.toString(command))); if (waitForExecution) { try { String commandOutput = output.readFully(); logger.debug(String.format("%s %s", nodeId, commandOutput)); } catch (Exception e) { logger.debug(nodeId + " Error while executing the output.readFully()", e); ga.trackException(e); } } } catch (DockerException | InterruptedException | NullPointerException e) { logger.debug(nodeId + " Error while executing the command", e); ga.trackException(e); } }
output = stream.readFully(); } catch (RuntimeException e) { handleExecStartConnectionReset(e);
@Test public void testDnsParam() throws Exception { final String server1 = "127.0.0.1"; final String server2 = "127.0.0.2"; startDefaultMaster(); startDefaultAgent(testHost(), "--dns", server1, "--dns", server2); awaitHostStatus(testHost(), UP, LONG_WAIT_SECONDS, SECONDS); final JobId jobId = createJob(testJobName, testJobVersion, BUSYBOX, asList("cat", "/etc/resolv.conf")); deployJob(jobId, testHost()); final TaskStatus taskStatus = awaitTaskState(jobId, testHost(), EXITED); try (final DockerClient dockerClient = getNewDockerClient()) { final LogStream logs = dockerClient.logs(taskStatus.getContainerId(), stdout(), stderr()); final String log = logs.readFully(); assertThat(log, containsString(server1)); assertThat(log, containsString(server2)); } }
@Before public void setup() throws Exception { try (final DockerClient docker = getNewDockerClient()) { // Build an image with an ENTRYPOINT and CMD prespecified final String dockerDirectory = Resources.getResource("syslog-test-image").getPath(); docker.build(Paths.get(dockerDirectory), testImage); // Figure out the host IP from the container's point of view (needed for syslog) final ContainerConfig config = ContainerConfig.builder() .image(BUSYBOX) .cmd(asList("ip", "route", "show")) .build(); final ContainerCreation creation = docker.createContainer(config); final String containerId = creation.id(); docker.startContainer(containerId); // Wait for the container to exit. // If we don't wait, docker.logs() might return an epmty string because the container // cmd hasn't run yet. docker.waitContainer(containerId); final String log; try (LogStream logs = docker.logs(containerId, stdout(), stderr())) { log = logs.readFully(); } final Matcher m = DEFAULT_GATEWAY_PATTERN.matcher(log); if (m.find()) { syslogHost = m.group("gateway"); } else { fail("couldn't determine the host address from '" + log + "'"); } } }
final String log = logs.readFully();
@Test public void testNoDnsParam() throws Exception { startDefaultMaster(); startDefaultAgent(testHost()); awaitHostStatus(testHost(), UP, LONG_WAIT_SECONDS, SECONDS); final JobId jobId = createJob(testJobName, testJobVersion, BUSYBOX, asList("cat", "/etc/resolv.conf")); deployJob(jobId, testHost()); final TaskStatus taskStatus = awaitTaskState(jobId, testHost(), EXITED); try (final DockerClient dockerClient = getNewDockerClient()) { final LogStream logs = dockerClient.logs(taskStatus.getContainerId(), stdout(), stderr()); final String log = logs.readFully(); // Verify that a nameserver is set even if we don't specify the --dns param assertThat(log, containsString("nameserver")); } }
@Test public void testPortEnvVars() throws Exception { startDefaultMaster(); startDefaultAgent(testHost()); awaitHostStatus(testHost(), UP, LONG_WAIT_SECONDS, SECONDS); final Map<String, PortMapping> ports = ImmutableMap.of("bar", staticMapping1); try (final DockerClient dockerClient = getNewDockerClient()) { final JobId jobId = createJob(testJobName + 1, testJobVersion, BUSYBOX, asList("sh", "-c", "echo $HELIOS_PORT_bar"), EMPTY_ENV, ports); deployJob(jobId, testHost()); final TaskStatus taskStatus = awaitTaskState(jobId, testHost(), EXITED); final String log; try (final LogStream logs = dockerClient.logs(taskStatus.getContainerId(), stdout(), stderr())) { log = logs.readFully(); } assertEquals(testHost() + ":" + externalPort1, log.trim()); } } }
@Test public void test() throws Exception { try (final DockerClient docker = getNewDockerClient()) { // Start Helios agent, configured to bind host /etc/hostname into container /mnt/hostname startDefaultMaster(); startDefaultAgent(testHost(), "--add-host", "secrethost:169.254.169.254"); awaitHostStatus(testHost(), UP, LONG_WAIT_SECONDS, SECONDS); // a job that cat's /etc/hosts final List<String> command = ImmutableList.of("cat", "/etc/hosts"); final JobId jobId = createJob(testJobName, testJobVersion, BUSYBOX, command); deployJob(jobId, testHost()); final TaskStatus taskStatus = awaitTaskState(jobId, testHost(), EXITED); final String log; try (LogStream logs = docker.logs(taskStatus.getContainerId(), stdout(), stderr())) { log = logs.readFully(); assertThat(log, containsString("169.254.169.254\tsecrethost")); } } } }
@Test public void test() throws Exception { try (final DockerClient docker = getNewDockerClient()) { // Start Helios agent, configured to bind host /etc/hostname into container /mnt/hostname startDefaultMaster(); startDefaultAgent(testHost(), "--bind", "/etc/hostname:/mnt/hostname:ro"); awaitHostStatus(testHost(), UP, LONG_WAIT_SECONDS, SECONDS); // Figure out the host kernel version final String hostname = docker.info().name(); // Run a job that cat's /mnt/hostname, which should be the host's name final List<String> command = ImmutableList.of("cat", "/mnt/hostname"); final JobId jobId = createJob(testJobName, testJobVersion, BUSYBOX, command); deployJob(jobId, testHost()); final TaskStatus taskStatus = awaitTaskState(jobId, testHost(), EXITED); final String log; try (LogStream logs = docker.logs(taskStatus.getContainerId(), stdout(), stderr())) { log = logs.readFully(); } // the kernel version from the host should be in the log assertThat(log, containsString(hostname)); } }
try (final LogStream logs = dockerClient.logs( taskStatus.getContainerId(), stdout(), stderr())) { log = logs.readFully();
@Test public void testTermOnExit() throws Exception { startDefaultMaster(); final String host = testHost(); startDefaultAgent(host); final HeliosClient client = defaultClient(); awaitHostStatus(client, host, UP, LONG_WAIT_SECONDS, SECONDS); // Note: signal 15 is SIGTERM final Job jobToInterrupt = Job.newBuilder() .setName(testJobName) .setVersion(testJobVersion) .setImage(BUSYBOX) .setCommand(asList("/bin/sh", "-c", "trap handle 15; handle() { echo term; exit 0; }; " + "while true; do sleep 1; done")) .build(); final JobId jobId = createJob(jobToInterrupt); deployJob(jobId, host); awaitTaskState(jobId, host, RUNNING); client.setGoal(new Deployment(jobId, Goal.STOP, Deployment.EMTPY_DEPLOYER_USER, Deployment.EMPTY_DEPLOYER_MASTER, Deployment.EMPTY_DEPLOYMENT_GROUP_NAME), host); final TaskStatus taskStatus = awaitTaskState(jobId, host, STOPPED); final String log; try (final DockerClient dockerClient = getNewDockerClient(); LogStream logs = dockerClient.logs(taskStatus.getContainerId(), stdout())) { log = logs.readFully(); } // Message expected, because the SIGTERM handler in the script should have run assertEquals("term\n", log); }
@Test public void testNoIntOnExit() throws Exception { startDefaultMaster(); final String host = testHost(); startDefaultAgent(host); final HeliosClient client = defaultClient(); awaitHostStatus(client, host, UP, LONG_WAIT_SECONDS, SECONDS); // Note: signal 2 is SIGINT final Job jobToInterrupt = Job.newBuilder() .setName(testJobName) .setVersion(testJobVersion) .setImage(BUSYBOX) .setCommand(asList("/bin/sh", "-c", "trap handle 2; handle() { echo int; exit 0; }; " + "while true; do sleep 1; done")) .build(); final JobId jobId = createJob(jobToInterrupt); deployJob(jobId, host); awaitTaskState(jobId, host, RUNNING); client.setGoal(new Deployment(jobId, Goal.STOP, Deployment.EMTPY_DEPLOYER_USER, Deployment.EMPTY_DEPLOYER_MASTER, Deployment.EMPTY_DEPLOYMENT_GROUP_NAME), host); final TaskStatus taskStatus = awaitTaskState(jobId, host, STOPPED); final String log; try (final DockerClient dockerClient = getNewDockerClient(); LogStream logs = dockerClient.logs(taskStatus.getContainerId(), stdout())) { log = logs.readFully(); } // No message expected, since SIGINT should not be sent assertEquals("", log); }
/** * GEts the logs for a specific container * @param containerId * @param from the number of lines to skip (to avoid killing the clients with giant logs */ private HashMap<String, Object> getContainerLogs(String containerId, int from) throws DockerException, InterruptedException { final String logs; try (LogStream stream = client.logs(containerId, DockerClient.LogsParam.stdout(), DockerClient.LogsParam.stderr())) { logs = stream.readFully(); } String[] split = logs.split("\n"); List<String> lines = Stream.of(split) .skip(from) .collect(Collectors.toList()); var result = new HashMap<String, Object>(); result.put("lines", lines); result.put("total", split.length); return result; } }
/** * Container log. */ public String getLog() { try (LogStream stream = dockerClient.logs(container.id(), LogsParam.stdout(), LogsParam.stderr());) { String fullLog = stream.readFully(); if (log.isTraceEnabled()) { log.trace("{} full log: {}", containerShortId, StringUtils.replace(fullLog, "\n", "|")); } return fullLog; } catch (DockerException | InterruptedException e) { throw new IllegalStateException(e); } }
/** * Collect logs from container and write to the log directory */ private void collectLogs() { if (!loggingParams.isEnabled()) { log.debug("Logging is disabled"); return; } File serverLogDir = loggingParams.getServerLogDir().toFile(); if (!serverLogDir.exists() && serverLogDir.mkdirs()) { log.info("Created new corfu log directory at {}.", serverLogDir); } log.debug("Collect logs for: {}", params.getName()); try (LogStream stream = docker.logs(params.getName(), LogsParam.stdout(), LogsParam.stderr())) { String logs = stream.readFully(); if (StringUtils.isEmpty(logs)) { log.warn("Empty logs from container: {}", params.getName()); } Path filePathObj = loggingParams.getServerLogDir().resolve(params.getName() + ".log"); Files.write(filePathObj, logs.getBytes(), StandardOpenOption.CREATE, StandardOpenOption.APPEND); } catch (InterruptedException | DockerException | IOException e) { log.error("Can't collect logs from container: {}", params.getName(), e); } }
@Override public boolean check(final String containerId) { // Make sure we are on a docker version that supports exec health checks if (!compatibleDockerVersion(docker)) { throw new UnsupportedOperationException( "docker exec healthcheck is not supported on your docker version"); } try { final List<String> cmd = healthCheck.getCommand(); final String execId = docker.execCreate(containerId, cmd.toArray(new String[cmd.size()]), DockerClient.ExecParameter.STDOUT, DockerClient.ExecParameter.STDERR); final String output; try (LogStream stream = docker.execStart(execId)) { output = stream.readFully(); } final int exitCode = docker.execInspect(execId).exitCode(); if (exitCode != 0) { log.info("healthcheck failed with exit code {}. output {}", exitCode, output); return false; } return true; } catch (DockerException e) { return false; } catch (InterruptedException e) { Thread.currentThread().interrupt(); return false; } }
public String execCommandInContainer(String containerId, String... command) throws DockerException, InterruptedException { String[] shCommand = { "sh", "-c" }; String[] finalCommand = (String[]) ArrayUtils.addAll(shCommand, command); String commandStr = Arrays.toString(finalCommand); log.trace("Running command {} in container {}", commandStr, containerId); String execId = dockerClient.execCreate(containerId, finalCommand, DockerClient.ExecCreateParam.attachStdout(), DockerClient.ExecCreateParam.attachStderr()).id(); String output = null; try (LogStream stream = dockerClient.execStart(execId)) { output = stream.readFully(); } log.trace("Result of command {} in container {}: {}", commandStr, containerId, output); return output; }
private TaskExecutionResult collectTaskExecutionResult(DockerTask task, String containerId) throws DockerException, InterruptedException { final ContainerExit exit = docker.waitContainer(containerId); log.info("Container " + containerId + " finished with exit code " + exit.statusCode()); TaskExecutionResult result = new TaskExecutionResult(task); // TODO : Do some descent exception treatment if (exit.statusCode() != 0) { result.markAsFinished(exit.statusCode()); } else { result.markAsFinishedWithSuccess(); } log.info("Collecting container logs for " + containerId); String logs = docker.logs(containerId, LogsParam.stdout(), LogsParam.stderr()).readFully(); // Remove the last new line if needed if (logs.endsWith("\n")) { logs = logs.substring(0, logs.length() - 1); } result.setOutput(logs); return result; }