Search in sources :

Example 1 with ContainerMount

use of com.spotify.docker.client.messages.ContainerMount in project TOSCAna by StuPro-TOSCAna.

the class PushingImageBuilderIT method tearDown.

@After
@SuppressWarnings("Duplicates")
public void tearDown() throws Exception {
    super.tearDown();
    DockerClient client = DefaultDockerClient.fromEnv().build();
    logger.info("Stopping and removing registry");
    List<ContainerMount> mounts = client.inspectContainer(this.registryId).mounts();
    client.killContainer(this.registryId);
    client.removeContainer(this.registryId);
    mounts.forEach(e -> {
        try {
            client.removeVolume(e.name());
        } catch (DockerException | InterruptedException ex) {
            ex.printStackTrace();
            throw new RuntimeException(ex);
        }
    });
}
Also used : DockerException(com.spotify.docker.client.exceptions.DockerException) DockerClient(com.spotify.docker.client.DockerClient) DefaultDockerClient(com.spotify.docker.client.DefaultDockerClient) ContainerMount(com.spotify.docker.client.messages.ContainerMount) After(org.junit.After)

Example 2 with ContainerMount

use of com.spotify.docker.client.messages.ContainerMount in project TOSCAna by StuPro-TOSCAna.

the class KubernetesPushingGopherIT method tearDown.

@After
@SuppressWarnings("Duplicates")
public void tearDown() throws Exception {
    DockerClient client = DefaultDockerClient.fromEnv().build();
    logger.info("Stopping and removing Containers");
    for (String id : runningContainers) {
        List<ContainerMount> mounts = client.inspectContainer(id).mounts();
        client.killContainer(id);
        client.removeContainer(id);
        mounts.forEach(e -> {
            try {
                client.removeVolume(e.name());
            } catch (DockerException | InterruptedException ex) {
                ex.printStackTrace();
                throw new RuntimeException(ex);
            }
        });
    }
    client.removeImage(getExpectedTag());
}
Also used : DockerException(com.spotify.docker.client.exceptions.DockerException) DockerClient(com.spotify.docker.client.DockerClient) DefaultDockerClient(com.spotify.docker.client.DefaultDockerClient) ContainerMount(com.spotify.docker.client.messages.ContainerMount) After(org.junit.After)

Example 3 with ContainerMount

use of com.spotify.docker.client.messages.ContainerMount in project docker-client by spotify.

the class DefaultDockerClientTest method testContainerVolumeNoCopy.

@Test
public void testContainerVolumeNoCopy() throws Exception {
    requireDockerApiVersionAtLeast("1.23", "Creating a container with volumes with nocopy mode");
    sut.pull(BUSYBOX_LATEST);
    final String aVolumeName = "avolume";
    final String aVolumeTo = "/some/path";
    final String nocopyVolumeName = "avolume2";
    final String nocopyVolumeTo = "/some/other/path";
    sut.createVolume(Volume.builder().name(aVolumeName).build());
    sut.createVolume(Volume.builder().name(nocopyVolumeName).build());
    final HostConfig hostConfig = HostConfig.builder().appendBinds(Bind.from(aVolumeName).to(aVolumeTo).readOnly(true).build()).appendBinds(Bind.from(nocopyVolumeName).to(nocopyVolumeTo).noCopy(true).build()).build();
    final ContainerConfig config = ContainerConfig.builder().image(BUSYBOX_LATEST).hostConfig(hostConfig).build();
    final String id = sut.createContainer(config, randomName()).id();
    final ContainerInfo info = sut.inspectContainer(id);
    final List<ContainerMount> mounts = info.mounts();
    assertThat(mounts.size(), equalTo(2));
    {
        final ContainerMount aMount = Iterables.find(mounts, new Predicate<ContainerMount>() {

            @Override
            public boolean apply(ContainerMount mount) {
                return !("nocopy".equals(mount.mode()));
            }
        }, null);
        assertThat("Could not find a mount (without nocopy)", aMount, notNullValue());
        assertThat(aMount.mode(), is(equalTo("ro")));
        assertThat(aMount.rw(), is(false));
        assertThat(aMount.source(), containsString("/" + aVolumeName + "/"));
        assertThat(aMount.destination(), is(equalTo(aVolumeTo)));
    }
    {
        final ContainerMount nocopyMount = Iterables.find(mounts, new Predicate<ContainerMount>() {

            @Override
            public boolean apply(ContainerMount mount) {
                return "nocopy".equals(mount.mode());
            }
        }, null);
        assertThat("Could not find mount (with nocopy)", nocopyMount, notNullValue());
        assertThat(nocopyMount.mode(), is(equalTo("nocopy")));
        assertThat(nocopyMount.rw(), is(true));
        assertThat(nocopyMount.source(), containsString("/" + nocopyVolumeName + "/"));
        assertThat(nocopyMount.destination(), is(equalTo(nocopyVolumeTo)));
    }
}
Also used : ContainerConfig(com.spotify.docker.client.messages.ContainerConfig) HostConfig(com.spotify.docker.client.messages.HostConfig) ContainerInfo(com.spotify.docker.client.messages.ContainerInfo) Long.toHexString(java.lang.Long.toHexString) Matchers.isEmptyOrNullString(org.hamcrest.Matchers.isEmptyOrNullString) Matchers.containsString(org.hamcrest.Matchers.containsString) ContainerMount(com.spotify.docker.client.messages.ContainerMount) Predicate(com.google.common.base.Predicate) Test(org.junit.Test)

Example 4 with ContainerMount

use of com.spotify.docker.client.messages.ContainerMount in project docker-client by spotify.

the class DefaultDockerClientTest method testContainerVolumes.

@Test
public void testContainerVolumes() throws Exception {
    requireDockerApiVersionAtLeast("1.20", "Creating a container with volumes and inspecting volumes");
    sut.pull(BUSYBOX_LATEST);
    final String namedVolumeName = "aVolume";
    final String namedVolumeFrom = "/a/host/path";
    final String namedVolumeTo = "/a/destination/path";
    final String bindObjectFrom = "/some/path";
    final String bindObjectTo = "/some/other/path";
    final String bindStringFrom = "/local/path";
    final String bindStringTo = "/remote/path";
    final String anonVolumeTo = "/foo";
    final Volume volume = Volume.builder().name(namedVolumeName).mountpoint(namedVolumeFrom).build();
    sut.createVolume(volume);
    final Bind bindUsingVolume = Bind.from(volume).to(namedVolumeTo).build();
    final Bind bind = Bind.from(bindObjectFrom).to(bindObjectTo).readOnly(true).build();
    final HostConfig hostConfig = HostConfig.builder().appendBinds(bind).appendBinds(bindStringFrom + ":" + bindStringTo).appendBinds(bindUsingVolume).build();
    final ContainerConfig volumeConfig = ContainerConfig.builder().image(BUSYBOX_LATEST).addVolume(anonVolumeTo).hostConfig(hostConfig).build();
    final String id = sut.createContainer(volumeConfig, randomName()).id();
    final ContainerInfo containerInfo = sut.inspectContainer(id);
    final List<ContainerMount> mounts = containerInfo.mounts();
    assertThat(mounts.size(), equalTo(4));
    {
        final ContainerMount bindObjectMount = Iterables.find(mounts, new Predicate<ContainerMount>() {

            @Override
            public boolean apply(ContainerMount mount) {
                return bindObjectFrom.equals(mount.source());
            }
        }, null);
        assertThat("Did not find mount from bind object", bindObjectMount, notNullValue());
        assertThat(bindObjectMount.source(), is(bindObjectFrom));
        assertThat(bindObjectMount.destination(), is(bindObjectTo));
        assertThat(bindObjectMount.driver(), isEmptyOrNullString());
        assertThat(bindObjectMount.rw(), is(false));
        assertThat(bindObjectMount.mode(), is(equalTo("ro")));
        if (dockerApiVersionAtLeast("1.25") && dockerApiVersionLessThan("1.30")) {
            // From version 1.25 to 1.29, the API behaved like this
            assertThat(bindObjectMount.name(), isEmptyOrNullString());
            assertThat(bindObjectMount.propagation(), isEmptyOrNullString());
        } else if (dockerApiVersionAtLeast("1.22") || dockerApiVersionAtLeast("1.30")) {
            // From version 1.22 to 1.24, and from 1.30 up, the API behaves like this
            assertThat(bindObjectMount.name(), isEmptyOrNullString());
            assertThat(bindObjectMount.propagation(), is(equalTo("rprivate")));
        } else {
            // Below version 1.22
            assertThat(bindObjectMount.name(), is(nullValue()));
            assertThat(bindObjectMount.propagation(), is(nullValue()));
        }
        if (dockerApiVersionAtLeast("1.26")) {
            assertThat(bindObjectMount.type(), is(equalTo("bind")));
            assertThat(bindObjectMount.driver(), isEmptyOrNullString());
        } else {
            assertThat(bindObjectMount.type(), is(nullValue()));
            assertThat(bindObjectMount.driver(), is(nullValue()));
        }
    }
    {
        final ContainerMount bindStringMount = Iterables.find(mounts, new Predicate<ContainerMount>() {

            @Override
            public boolean apply(ContainerMount mount) {
                return bindStringFrom.equals(mount.source());
            }
        }, null);
        assertThat("Did not find mount from bind string", bindStringMount, notNullValue());
        assertThat(bindStringMount.source(), is(equalTo(bindStringFrom)));
        assertThat(bindStringMount.destination(), is(equalTo(bindStringTo)));
        assertThat(bindStringMount.driver(), isEmptyOrNullString());
        assertThat(bindStringMount.rw(), is(true));
        assertThat(bindStringMount.mode(), is(equalTo("")));
        if (dockerApiVersionAtLeast("1.25") && dockerApiVersionLessThan("1.30")) {
            // From version 1.25 to 1.29, the API behaved like this
            assertThat(bindStringMount.name(), isEmptyOrNullString());
            assertThat(bindStringMount.propagation(), isEmptyOrNullString());
        } else if (dockerApiVersionAtLeast("1.22") || dockerApiVersionAtLeast("1.30")) {
            // From version 1.22 to 1.24, and from 1.30 up, the API behaves like this
            assertThat(bindStringMount.name(), isEmptyOrNullString());
            assertThat(bindStringMount.propagation(), is(equalTo("rprivate")));
        } else {
            // Below version 1.22
            assertThat(bindStringMount.name(), is(nullValue()));
            assertThat(bindStringMount.propagation(), is(nullValue()));
        }
        if (dockerApiVersionAtLeast("1.26")) {
            assertThat(bindStringMount.type(), is(equalTo("bind")));
            assertThat(bindStringMount.driver(), isEmptyOrNullString());
        } else {
            assertThat(bindStringMount.type(), is(nullValue()));
            assertThat(bindStringMount.driver(), is(nullValue()));
        }
    }
    {
        final ContainerMount namedVolumeMount = Iterables.find(mounts, new Predicate<ContainerMount>() {

            @Override
            public boolean apply(ContainerMount mount) {
                return namedVolumeTo.equals(mount.destination());
            }
        }, null);
        assertThat("Did not find mount from named volume", namedVolumeMount, notNullValue());
        assertThat(namedVolumeMount.name(), is(equalTo(namedVolumeName)));
        assertThat(namedVolumeMount.source(), containsString("/" + namedVolumeName + "/"));
        assertThat(namedVolumeMount.destination(), is(equalTo(namedVolumeTo)));
        assertThat(namedVolumeMount.rw(), is(true));
        assertThat(namedVolumeMount.mode(), is(equalTo("z")));
        assertThat(namedVolumeMount.name(), is(namedVolumeName));
        assertThat(namedVolumeMount.driver(), is(equalTo("local")));
        if (dockerApiVersionAtLeast("1.25")) {
            assertThat(namedVolumeMount.propagation(), isEmptyOrNullString());
        } else if (dockerApiVersionAtLeast("1.22")) {
            assertThat(namedVolumeMount.propagation(), is(equalTo("rprivate")));
        } else {
            assertThat(namedVolumeMount.propagation(), is(nullValue()));
        }
        if (dockerApiVersionAtLeast("1.26")) {
            assertThat(namedVolumeMount.type(), is(equalTo("volume")));
        } else {
            assertThat(namedVolumeMount.type(), is(nullValue()));
        }
    }
    {
        final ContainerMount anonVolumeMount = Iterables.find(mounts, new Predicate<ContainerMount>() {

            @Override
            public boolean apply(ContainerMount mount) {
                return anonVolumeTo.equals(mount.destination());
            }
        }, null);
        assertThat("Did not find mount from anonymous volume", anonVolumeMount, notNullValue());
        assertThat(anonVolumeMount.source(), containsString("/" + anonVolumeMount.name() + "/"));
        assertThat(anonVolumeMount.destination(), is(equalTo(anonVolumeTo)));
        assertThat(anonVolumeMount.mode(), isEmptyOrNullString());
        assertThat(anonVolumeMount.rw(), is(true));
        assertThat(anonVolumeMount.mode(), is(equalTo("")));
        assertThat(anonVolumeMount.name(), not(isEmptyOrNullString()));
        assertThat(anonVolumeMount.driver(), is(equalTo("local")));
        if (dockerApiVersionAtLeast("1.22")) {
            assertThat(anonVolumeMount.propagation(), isEmptyOrNullString());
        } else {
            assertThat(anonVolumeMount.propagation(), is(nullValue()));
        }
        if (dockerApiVersionAtLeast("1.26")) {
            assertThat(anonVolumeMount.type(), is(equalTo("volume")));
        } else {
            assertThat(anonVolumeMount.type(), is(nullValue()));
        }
    }
    assertThat(containerInfo.config().volumes(), hasItem(anonVolumeTo));
}
Also used : ContainerConfig(com.spotify.docker.client.messages.ContainerConfig) Bind(com.spotify.docker.client.messages.HostConfig.Bind) SecretBind(com.spotify.docker.client.messages.swarm.SecretBind) Volume(com.spotify.docker.client.messages.Volume) HostConfig(com.spotify.docker.client.messages.HostConfig) ContainerInfo(com.spotify.docker.client.messages.ContainerInfo) Long.toHexString(java.lang.Long.toHexString) Matchers.isEmptyOrNullString(org.hamcrest.Matchers.isEmptyOrNullString) Matchers.containsString(org.hamcrest.Matchers.containsString) ContainerMount(com.spotify.docker.client.messages.ContainerMount) Predicate(com.google.common.base.Predicate) Test(org.junit.Test)

Example 5 with ContainerMount

use of com.spotify.docker.client.messages.ContainerMount in project zalenium by zalando.

the class DockerContainerMock method getMockedDockerContainerClient.

@SuppressWarnings("ConstantConditions")
public static DockerContainerClient getMockedDockerContainerClient(String networkName) {
    DockerClient dockerClient = mock(DockerClient.class);
    ExecCreation execCreation = mock(ExecCreation.class);
    LogStream logStream = mock(LogStream.class);
    when(logStream.readFully()).thenReturn("ANY_STRING");
    when(execCreation.id()).thenReturn("ANY_ID");
    ContainerCreation containerCreation = mock(ContainerCreation.class);
    when(containerCreation.id()).thenReturn("ANY_CONTAINER_ID");
    AttachedNetwork attachedNetwork = mock(AttachedNetwork.class);
    NetworkSettings networkSettings = mock(NetworkSettings.class);
    HostConfig hostConfig = mock(HostConfig.class);
    ImageInfo imageInfo = mock(ImageInfo.class);
    ContainerConfig containerConfig = mock(ContainerConfig.class);
    ContainerInfo containerInfo = mock(ContainerInfo.class);
    ContainerMount tmpMountedMount = mock(ContainerMount.class);
    when(tmpMountedMount.destination()).thenReturn("/tmp/node/tmp/mounted");
    when(tmpMountedMount.source()).thenReturn("/tmp/mounted");
    ContainerMount homeFolderMount = mock(ContainerMount.class);
    when(homeFolderMount.destination()).thenReturn("/tmp/node/home/seluser/folder");
    when(homeFolderMount.source()).thenReturn("/tmp/folder");
    when(containerInfo.mounts()).thenReturn(ImmutableList.of(tmpMountedMount, homeFolderMount));
    when(attachedNetwork.ipAddress()).thenReturn("127.0.0.1");
    when(networkSettings.networks()).thenReturn(ImmutableMap.of(networkName, attachedNetwork));
    when(networkSettings.ipAddress()).thenReturn("");
    when(containerInfo.networkSettings()).thenReturn(networkSettings);
    when(hostConfig.extraHosts()).thenReturn(null);
    when(containerInfo.hostConfig()).thenReturn(hostConfig);
    String[] httpEnvVars = { "zalenium_http_proxy=http://34.211.100.239:8080", "zalenium_https_proxy=http://34.211.100.239:8080" };
    when(containerConfig.env()).thenReturn(ImmutableList.copyOf(Arrays.asList(httpEnvVars)));
    when(containerInfo.config()).thenReturn(containerConfig);
    String containerId = RandomStringUtils.randomAlphabetic(30).toLowerCase();
    Container container_40000 = mock(Container.class);
    when(container_40000.names()).thenReturn(ImmutableList.copyOf(Collections.singletonList("/zalenium_40000")));
    when(container_40000.id()).thenReturn(containerId);
    when(container_40000.status()).thenReturn("running");
    when(container_40000.image()).thenReturn("elgalu/selenium");
    Container container_40001 = mock(Container.class);
    when(container_40001.names()).thenReturn(ImmutableList.copyOf(Collections.singletonList("/zalenium_40001")));
    when(container_40001.id()).thenReturn(containerId);
    when(container_40001.status()).thenReturn("running");
    when(container_40001.image()).thenReturn("elgalu/selenium");
    String zaleniumContainerId = RandomStringUtils.randomAlphabetic(30).toLowerCase();
    Container zalenium = mock(Container.class);
    when(zalenium.names()).thenReturn(ImmutableList.copyOf(Collections.singletonList("/zalenium")));
    when(zalenium.id()).thenReturn(zaleniumContainerId);
    when(zalenium.status()).thenReturn("running");
    when(zalenium.image()).thenReturn("dosel/zalenium");
    Info dockerInfo = mock(Info.class);
    when(dockerInfo.name()).thenReturn("ubuntu_vm");
    try {
        URL logsLocation = TestUtils.class.getClassLoader().getResource("logs.tar");
        URL videosLocation = TestUtils.class.getClassLoader().getResource("videos.tar");
        File logsFile = new File(logsLocation.getPath());
        File videosFile = new File(videosLocation.getPath());
        when(dockerClient.archiveContainer(containerId, "/var/log/cont/")).thenReturn(new FileInputStream(logsFile));
        when(dockerClient.archiveContainer(containerId, "/videos/")).thenReturn(new FileInputStream(videosFile));
        String[] startVideo = { "bash", "-c", START_RECORDING.getContainerAction() };
        String[] stopVideo = { "bash", "-c", STOP_RECORDING.getContainerAction() };
        String[] transferLogs = { "bash", "-c", TRANSFER_LOGS.getContainerAction() };
        String[] cleanupContainer = { "bash", "-c", CLEANUP_CONTAINER.getContainerAction() };
        String[] sendNotificationCompleted = { "bash", "-c", SEND_NOTIFICATION.getContainerAction().concat(COMPLETED.getTestNotificationMessage()) };
        String[] sendNotificationTimeout = { "bash", "-c", SEND_NOTIFICATION.getContainerAction().concat(TIMEOUT.getTestNotificationMessage()) };
        when(dockerClient.execCreate(containerId, startVideo, DockerClient.ExecCreateParam.attachStdout(), DockerClient.ExecCreateParam.attachStderr(), DockerClient.ExecCreateParam.attachStdin())).thenReturn(execCreation);
        when(dockerClient.execCreate(containerId, stopVideo, DockerClient.ExecCreateParam.attachStdout(), DockerClient.ExecCreateParam.attachStderr(), DockerClient.ExecCreateParam.attachStdin())).thenReturn(execCreation);
        when(dockerClient.execCreate(containerId, transferLogs, DockerClient.ExecCreateParam.attachStdout(), DockerClient.ExecCreateParam.attachStderr(), DockerClient.ExecCreateParam.attachStdin())).thenReturn(execCreation);
        when(dockerClient.execCreate(containerId, cleanupContainer, DockerClient.ExecCreateParam.attachStdout(), DockerClient.ExecCreateParam.attachStderr(), DockerClient.ExecCreateParam.attachStdin())).thenReturn(execCreation);
        when(dockerClient.execCreate(containerId, sendNotificationCompleted, DockerClient.ExecCreateParam.attachStdout(), DockerClient.ExecCreateParam.attachStderr(), DockerClient.ExecCreateParam.attachStdin())).thenReturn(execCreation);
        when(dockerClient.execCreate(containerId, sendNotificationTimeout, DockerClient.ExecCreateParam.attachStdout(), DockerClient.ExecCreateParam.attachStderr(), DockerClient.ExecCreateParam.attachStdin())).thenReturn(execCreation);
        when(dockerClient.execStart(anyString())).thenReturn(logStream);
        doNothing().when(dockerClient).stopContainer(anyString(), anyInt());
        when(dockerClient.info()).thenReturn(dockerInfo);
        when(dockerClient.createContainer(any(ContainerConfig.class), anyString())).thenReturn(containerCreation);
        when(dockerClient.listContainers(DockerClient.ListContainersParam.allContainers())).thenReturn(Arrays.asList(container_40000, container_40001, zalenium));
        when(containerConfig.labels()).thenReturn(ImmutableMap.of("selenium_firefox_version", "52", "selenium_chrome_version", "58"));
        when(imageInfo.config()).thenReturn(containerConfig);
        when(dockerClient.inspectContainer(null)).thenReturn(containerInfo);
        when(dockerClient.inspectContainer(zaleniumContainerId)).thenReturn(containerInfo);
        when(dockerClient.inspectContainer(containerId)).thenReturn(containerInfo);
        when(dockerClient.inspectImage(anyString())).thenReturn(imageInfo);
        when(dockerClient.listImages(DockerClient.ListImagesParam.byName("elgalu/selenium"))).thenReturn(Collections.emptyList());
    } catch (DockerException | InterruptedException | IOException e) {
        e.printStackTrace();
    }
    DockerContainerClient dockerContainerClient = new DockerContainerClient();
    dockerContainerClient.setContainerClient(dockerClient);
    return dockerContainerClient;
}
Also used : DockerException(com.spotify.docker.client.exceptions.DockerException) DockerClient(com.spotify.docker.client.DockerClient) DockerContainerClient(de.zalando.ep.zalenium.container.DockerContainerClient) LogStream(com.spotify.docker.client.LogStream) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) IOException(java.io.IOException) Info(com.spotify.docker.client.messages.Info) ContainerInfo(com.spotify.docker.client.messages.ContainerInfo) ImageInfo(com.spotify.docker.client.messages.ImageInfo) URL(java.net.URL) FileInputStream(java.io.FileInputStream) AttachedNetwork(com.spotify.docker.client.messages.AttachedNetwork) ContainerConfig(com.spotify.docker.client.messages.ContainerConfig) ExecCreation(com.spotify.docker.client.messages.ExecCreation) ContainerCreation(com.spotify.docker.client.messages.ContainerCreation) NetworkSettings(com.spotify.docker.client.messages.NetworkSettings) Container(com.spotify.docker.client.messages.Container) HostConfig(com.spotify.docker.client.messages.HostConfig) ContainerInfo(com.spotify.docker.client.messages.ContainerInfo) ImageInfo(com.spotify.docker.client.messages.ImageInfo) File(java.io.File) ContainerMount(com.spotify.docker.client.messages.ContainerMount)

Aggregations

ContainerMount (com.spotify.docker.client.messages.ContainerMount)5 DockerClient (com.spotify.docker.client.DockerClient)3 DockerException (com.spotify.docker.client.exceptions.DockerException)3 ContainerConfig (com.spotify.docker.client.messages.ContainerConfig)3 ContainerInfo (com.spotify.docker.client.messages.ContainerInfo)3 HostConfig (com.spotify.docker.client.messages.HostConfig)3 Predicate (com.google.common.base.Predicate)2 DefaultDockerClient (com.spotify.docker.client.DefaultDockerClient)2 Long.toHexString (java.lang.Long.toHexString)2 Matchers.containsString (org.hamcrest.Matchers.containsString)2 Matchers.isEmptyOrNullString (org.hamcrest.Matchers.isEmptyOrNullString)2 After (org.junit.After)2 Test (org.junit.Test)2 LogStream (com.spotify.docker.client.LogStream)1 AttachedNetwork (com.spotify.docker.client.messages.AttachedNetwork)1 Container (com.spotify.docker.client.messages.Container)1 ContainerCreation (com.spotify.docker.client.messages.ContainerCreation)1 ExecCreation (com.spotify.docker.client.messages.ExecCreation)1 Bind (com.spotify.docker.client.messages.HostConfig.Bind)1 ImageInfo (com.spotify.docker.client.messages.ImageInfo)1