Search in sources :

Example 1 with ImageInfo

use of com.spotify.docker.client.messages.ImageInfo in project helios by spotify.

the class SupervisorTest method verifySupervisorRestartsExitedContainer.

@Test
public void verifySupervisorRestartsExitedContainer() throws Exception {
    final String containerId1 = "deadbeef1";
    final String containerId2 = "deadbeef2";
    final ContainerCreation createResponse1 = ContainerCreation.builder().id(containerId1).build();
    final ContainerCreation createResponse2 = ContainerCreation.builder().id(containerId2).build();
    when(docker.createContainer(any(ContainerConfig.class), any(String.class))).thenReturn(createResponse1);
    final ImageInfo imageInfo = mock(ImageInfo.class);
    when(docker.inspectImage(IMAGE)).thenReturn(imageInfo);
    when(docker.inspectContainer(eq(containerId1))).thenReturn(runningResponse);
    final SettableFuture<ContainerExit> waitFuture1 = SettableFuture.create();
    final SettableFuture<ContainerExit> waitFuture2 = SettableFuture.create();
    when(docker.waitContainer(containerId1)).thenAnswer(futureAnswer(waitFuture1));
    when(docker.waitContainer(containerId2)).thenAnswer(futureAnswer(waitFuture2));
    // Start the job
    sut.setGoal(START);
    verify(docker, timeout(30000)).createContainer(any(ContainerConfig.class), any(String.class));
    verify(docker, timeout(30000)).startContainer(eq(containerId1));
    verify(docker, timeout(30000)).waitContainer(containerId1);
    // Indicate that the container exited
    when(docker.inspectContainer(eq(containerId1))).thenReturn(stoppedResponse);
    when(docker.createContainer(any(ContainerConfig.class), any(String.class))).thenReturn(createResponse2);
    when(docker.inspectContainer(eq(containerId2))).thenReturn(runningResponse);
    waitFuture1.set(ContainerExit.create(1));
    // Verify that the container was restarted
    verify(docker, timeout(30000)).createContainer(any(ContainerConfig.class), any(String.class));
    verify(docker, timeout(30000)).startContainer(eq(containerId2));
    verify(docker, timeout(30000)).waitContainer(containerId2);
}
Also used : ContainerConfig(com.spotify.docker.client.messages.ContainerConfig) ContainerCreation(com.spotify.docker.client.messages.ContainerCreation) ContainerExit(com.spotify.docker.client.messages.ContainerExit) ImageInfo(com.spotify.docker.client.messages.ImageInfo) Test(org.junit.Test)

Example 2 with ImageInfo

use of com.spotify.docker.client.messages.ImageInfo in project helios by spotify.

the class TaskRunner method startContainer.

private String startContainer(final String image, final Optional<String> dockerVersion) throws InterruptedException, DockerException {
    // Get container image info
    final ImageInfo imageInfo = docker.inspectImage(image);
    if (imageInfo == null) {
        throw new HeliosRuntimeException("docker inspect image returned null on image " + image);
    }
    // Create container
    final HostConfig hostConfig = config.hostConfig(dockerVersion);
    final ContainerConfig containerConfig = config.containerConfig(imageInfo, dockerVersion).toBuilder().hostConfig(hostConfig).build();
    listener.creating();
    final ContainerCreation container = docker.createContainer(containerConfig, containerName);
    log.info("created container: {}: {}, {}", config, container, containerConfig);
    listener.created(container.id());
    // Start container
    log.info("starting container: {}: {} {}", config, container.id(), hostConfig);
    listener.starting();
    docker.startContainer(container.id());
    log.info("started container: {}: {}", config, container.id());
    listener.started();
    return container.id();
}
Also used : ContainerConfig(com.spotify.docker.client.messages.ContainerConfig) ContainerCreation(com.spotify.docker.client.messages.ContainerCreation) HeliosRuntimeException(com.spotify.helios.common.HeliosRuntimeException) HostConfig(com.spotify.docker.client.messages.HostConfig) ImageInfo(com.spotify.docker.client.messages.ImageInfo)

Example 3 with ImageInfo

use of com.spotify.docker.client.messages.ImageInfo in project helios by spotify.

the class GracePeriodTest method verifySupervisorStartsAndStopsDockerContainer.

@Test
public void verifySupervisorStartsAndStopsDockerContainer() throws Exception {
    final String containerId = "deadbeef";
    final ContainerCreation createResponse = ContainerCreation.builder().id(containerId).build();
    final SettableFuture<ContainerCreation> createFuture = SettableFuture.create();
    when(docker.createContainer(any(ContainerConfig.class), any(String.class))).thenAnswer(futureAnswer(createFuture));
    final SettableFuture<Void> startFuture = SettableFuture.create();
    doAnswer(futureAnswer(startFuture)).when(docker).startContainer(eq(containerId));
    final ImageInfo imageInfo = mock(ImageInfo.class);
    when(docker.inspectImage(IMAGE)).thenReturn(imageInfo);
    final SettableFuture<ContainerExit> waitFuture = SettableFuture.create();
    when(docker.waitContainer(containerId)).thenAnswer(futureAnswer(waitFuture));
    // Start the job
    sut.setGoal(START);
    // Verify that the pulling state is signalled
    verify(model, timeout(30000)).setTaskStatus(eq(JOB.getId()), eq(TaskStatus.newBuilder().setJob(JOB).setGoal(START).setState(PULLING_IMAGE).setPorts(PORTS).setContainerId(null).setEnv(ENV).build()));
    // Verify that the container is created
    verify(docker, timeout(30000)).createContainer(containerConfigCaptor.capture(), containerNameCaptor.capture());
    verify(model, timeout(30000)).setTaskStatus(eq(JOB.getId()), eq(TaskStatus.newBuilder().setJob(JOB).setGoal(START).setState(CREATING).setPorts(PORTS).setContainerId(null).setEnv(ENV).build()));
    createFuture.set(createResponse);
    final ContainerConfig containerConfig = containerConfigCaptor.getValue();
    assertEquals(IMAGE, containerConfig.image());
    assertEquals(EXPECTED_CONTAINER_ENV, ImmutableSet.copyOf(containerConfig.env()));
    final String containerName = containerNameCaptor.getValue();
    assertEquals(JOB.getId().toShortString(), shortJobIdFromContainerName(containerName));
    // Verify that the container is started
    verify(docker, timeout(30000)).startContainer(eq(containerId));
    verify(model, timeout(30000)).setTaskStatus(eq(JOB.getId()), eq(TaskStatus.newBuilder().setJob(JOB).setGoal(START).setState(STARTING).setPorts(PORTS).setContainerId(containerId).setEnv(ENV).build()));
    when(docker.inspectContainer(eq(containerId))).thenReturn(runningResponse);
    startFuture.set(null);
    verify(docker, timeout(30000)).waitContainer(containerId);
    verify(model, timeout(30000)).setTaskStatus(eq(JOB.getId()), eq(TaskStatus.newBuilder().setJob(JOB).setGoal(START).setState(RUNNING).setPorts(PORTS).setContainerId(containerId).setEnv(ENV).build()));
    // Stop the job
    final SettableFuture<Void> killFuture = SettableFuture.create();
    doAnswer(futureAnswer(killFuture)).when(docker).killContainer(eq(containerId));
    executor.submit(new Callable<Void>() {

        @Override
        public Void call() throws Exception {
            // TODO (dano): Make Supervisor.stop() asynchronous
            sut.setGoal(STOP);
            return null;
        }
    });
    // Stop the container
    verify(docker, timeout(30000)).killContainer(eq(containerId));
    // Verify that Sleeper has been called and that datetime has increased by
    // GRACE_PERIOD number of milliseconds
    verify(sleeper).sleep(GRACE_PERIOD_MILLIS);
    // Change docker container state to stopped when it's killed
    when(docker.inspectContainer(eq(containerId))).thenReturn(stoppedResponse);
    killFuture.set(null);
    // Verify that the stopping state is signalled
    verify(model, timeout(30000)).setTaskStatus(eq(JOB.getId()), eq(TaskStatus.newBuilder().setJob(JOB).setGoal(STOP).setState(STOPPING).setPorts(PORTS).setContainerId(containerId).setEnv(ENV).build()));
    // Verify that the stopped state is signalled
    verify(model, timeout(30000)).setTaskStatus(eq(JOB.getId()), eq(TaskStatus.newBuilder().setJob(JOB).setGoal(STOP).setState(STOPPED).setPorts(PORTS).setContainerId(containerId).setEnv(ENV).build()));
}
Also used : ContainerConfig(com.spotify.docker.client.messages.ContainerConfig) ContainerCreation(com.spotify.docker.client.messages.ContainerCreation) ContainerExit(com.spotify.docker.client.messages.ContainerExit) ImageInfo(com.spotify.docker.client.messages.ImageInfo) Test(org.junit.Test)

Example 4 with ImageInfo

use of com.spotify.docker.client.messages.ImageInfo in project helios by spotify.

the class SupervisorTest method verifySupervisorStartsAndStopsDockerContainer.

@Test
public void verifySupervisorStartsAndStopsDockerContainer() throws Exception {
    final String containerId = "deadbeef";
    when(docker.createContainer(any(ContainerConfig.class), any(String.class))).thenReturn(ContainerCreation.builder().id(containerId).build());
    final ImageInfo imageInfo = mock(ImageInfo.class);
    when(docker.inspectImage(IMAGE)).thenReturn(imageInfo);
    // Have waitContainer wait forever.
    final SettableFuture<ContainerExit> waitFuture = SettableFuture.create();
    when(docker.waitContainer(containerId)).thenAnswer(futureAnswer(waitFuture));
    // Start the job
    sut.setGoal(START);
    // Verify that the container is created
    verify(docker, timeout(30000)).createContainer(containerConfigCaptor.capture(), containerNameCaptor.capture());
    verify(model, timeout(30000)).setTaskStatus(eq(JOB.getId()), eq(TaskStatus.newBuilder().setJob(JOB).setGoal(START).setState(CREATING).setContainerId(null).setEnv(ENV).build()));
    final ContainerConfig containerConfig = containerConfigCaptor.getValue();
    assertEquals(IMAGE, containerConfig.image());
    assertEquals(EXPECTED_CONTAINER_ENV, ImmutableSet.copyOf(containerConfig.env()));
    final String containerName = containerNameCaptor.getValue();
    assertEquals(JOB.getId().toShortString(), shortJobIdFromContainerName(containerName));
    // Verify that the container is started
    verify(docker, timeout(30000)).startContainer(eq(containerId));
    verify(model, timeout(30000)).setTaskStatus(eq(JOB.getId()), eq(TaskStatus.newBuilder().setJob(JOB).setGoal(START).setState(STARTING).setContainerId(containerId).setEnv(ENV).build()));
    when(docker.inspectContainer(eq(containerId))).thenReturn(runningResponse);
    verify(docker, timeout(30000)).waitContainer(containerId);
    verify(model, timeout(30000)).setTaskStatus(eq(JOB.getId()), eq(TaskStatus.newBuilder().setJob(JOB).setGoal(START).setState(RUNNING).setContainerId(containerId).setEnv(ENV).build()));
    // Stop the job
    sut.setGoal(STOP);
    verify(docker, timeout(30000)).stopContainer(eq(containerId), eq(Supervisor.DEFAULT_SECONDS_TO_WAIT_BEFORE_KILL));
    // Change docker container state to stopped now that it was killed
    when(docker.inspectContainer(eq(containerId))).thenReturn(stoppedResponse);
    // Verify that the pulling state is signalled
    verify(model, timeout(30000)).setTaskStatus(eq(JOB.getId()), eq(TaskStatus.newBuilder().setJob(JOB).setGoal(START).setState(PULLING_IMAGE).setContainerId(null).setEnv(ENV).build()));
    // Verify that the STOPPING and STOPPED states are signalled
    verify(model, timeout(30000)).setTaskStatus(eq(JOB.getId()), eq(TaskStatus.newBuilder().setJob(JOB).setGoal(STOP).setState(STOPPING).setContainerId(containerId).setEnv(ENV).build()));
    verify(model, timeout(30000)).setTaskStatus(eq(JOB.getId()), eq(TaskStatus.newBuilder().setJob(JOB).setGoal(STOP).setState(STOPPED).setContainerId(containerId).setEnv(ENV).build()));
}
Also used : ContainerConfig(com.spotify.docker.client.messages.ContainerConfig) ContainerExit(com.spotify.docker.client.messages.ContainerExit) ImageInfo(com.spotify.docker.client.messages.ImageInfo) Test(org.junit.Test)

Example 5 with ImageInfo

use of com.spotify.docker.client.messages.ImageInfo in project helios by spotify.

the class TaskRunnerTest method testContainerNotRunningVariation.

@Test
public void testContainerNotRunningVariation() throws Throwable {
    final TaskRunner.NopListener mockListener = mock(TaskRunner.NopListener.class);
    final ImageInfo mockImageInfo = mock(ImageInfo.class);
    final ContainerCreation mockCreation = mock(ContainerCreation.class);
    final HealthChecker mockHealthChecker = mock(HealthChecker.class);
    final ContainerState stoppedState = mock(ContainerState.class);
    when(stoppedState.running()).thenReturn(false);
    when(stoppedState.error()).thenReturn("container is a potato");
    final ContainerInfo stopped = mock(ContainerInfo.class);
    when(stopped.state()).thenReturn(stoppedState);
    when(mockCreation.id()).thenReturn("potato");
    when(mockDocker.inspectContainer(anyString())).thenReturn(stopped);
    when(mockDocker.inspectImage(IMAGE)).thenReturn(mockImageInfo);
    when(mockDocker.createContainer(any(ContainerConfig.class), anyString())).thenReturn(mockCreation);
    when(mockHealthChecker.check(anyString())).thenReturn(false);
    final TaskRunner tr = TaskRunner.builder().delayMillis(0).config(TaskConfig.builder().namespace("test").host(HOST).job(JOB).containerDecorators(ImmutableList.of(containerDecorator)).build()).docker(mockDocker).listener(mockListener).healthChecker(mockHealthChecker).build();
    tr.run();
    try {
        tr.resultFuture().get();
        fail("this should throw");
    } catch (Exception t) {
        assertTrue(t instanceof ExecutionException);
        assertEquals(RuntimeException.class, t.getCause().getClass());
        verify(mockListener).failed(t.getCause(), "container is a potato");
    }
}
Also used : ContainerConfig(com.spotify.docker.client.messages.ContainerConfig) ContainerCreation(com.spotify.docker.client.messages.ContainerCreation) HeliosRuntimeException(com.spotify.helios.common.HeliosRuntimeException) ContainerInfo(com.spotify.docker.client.messages.ContainerInfo) ImageInfo(com.spotify.docker.client.messages.ImageInfo) ExecutionException(java.util.concurrent.ExecutionException) ContainerState(com.spotify.docker.client.messages.ContainerState) HeliosRuntimeException(com.spotify.helios.common.HeliosRuntimeException) DockerException(com.spotify.docker.client.exceptions.DockerException) ImageNotFoundException(com.spotify.docker.client.exceptions.ImageNotFoundException) DockerTimeoutException(com.spotify.docker.client.exceptions.DockerTimeoutException) ExecutionException(java.util.concurrent.ExecutionException) ImagePullFailedException(com.spotify.docker.client.exceptions.ImagePullFailedException) Test(org.junit.Test)

Aggregations

ContainerConfig (com.spotify.docker.client.messages.ContainerConfig)6 ImageInfo (com.spotify.docker.client.messages.ImageInfo)6 Test (org.junit.Test)5 ContainerCreation (com.spotify.docker.client.messages.ContainerCreation)4 ContainerExit (com.spotify.docker.client.messages.ContainerExit)4 HeliosRuntimeException (com.spotify.helios.common.HeliosRuntimeException)2 DockerException (com.spotify.docker.client.exceptions.DockerException)1 DockerTimeoutException (com.spotify.docker.client.exceptions.DockerTimeoutException)1 ImageNotFoundException (com.spotify.docker.client.exceptions.ImageNotFoundException)1 ImagePullFailedException (com.spotify.docker.client.exceptions.ImagePullFailedException)1 ContainerInfo (com.spotify.docker.client.messages.ContainerInfo)1 ContainerState (com.spotify.docker.client.messages.ContainerState)1 HostConfig (com.spotify.docker.client.messages.HostConfig)1 Job (com.spotify.helios.common.descriptors.Job)1 ExecutionException (java.util.concurrent.ExecutionException)1