docker / docker/docker-py

Container create/run/attach hangs if container exits immediately

Open
#2,087 5 comments 4 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
7.2k
Forks
1.7k
Avg merge
13d 8h
Merged PRs (30d)
2

Description

Docker-py version: 3.4.1
Python version: 3.6.6, 3.6.0

Please see "this line is never reached at all". This container is correctly identified as "exited" by the command-line tools. If I subsequently delete the container the test case will still hang forever.

>> docker version
Server:
 Engine:
  Version:	17.12.1-ce
  API version:	1.35 (minimum version 1.12)
  Go version:	go1.10.1
  Git commit:	7390fc6
  Built:	Wed Feb 28 17:46:05 2018
  OS/Arch:	linux/amd64
  Experimental:	false

Failing test case:

import json
import subprocess
import unittest
from contextlib import closing
from time import sleep

from docker import DockerClient
from docker.types import ContainerConfig


def run_shell(*cmd):
    popen = subprocess.Popen(cmd, stdout=subprocess.PIPE, universal_newlines=True)

    try:
        return json.loads(popen.stdout.read())[0]
    finally:
        popen.stdout.close()


class TestDockerError(unittest.TestCase):
    def test_create_attach_clean(self):
        try:
            with closing(DockerClient('unix:///var/run/docker.sock')) as cli:
                c = cli.containers.create(
                    image='alpine:3.5',
                    command=['sh', '-c', 'echo asd'],
                    name='test_simple'
                )
                c.start()

                print(c.status)  # created
                print(run_shell('docker', 'inspect', 'test_simple')['State']['Status'])  # running
                sleep(5)

                print(c.status)  # created
                print(run_shell('docker', 'inspect', 'test_simple')['State']['Status'])  # exited

                for log in c.attach(stream=True, logs=True):
                    print(log)  # b'asd\n'

                # todo this line is never reached at all

        finally:
            try:
                with closing(DockerClient('unix:///var/run/docker.sock')) as cli:
                    cli.api.remove_container('test_simple')
            except:
                pass

    def test_create_attach_bare(self):
        try:
            with closing(DockerClient('unix:///var/run/docker.sock')) as cli:
                c = cli.api.create_container_from_config(
                    config=ContainerConfig(
                        detach=True,
                        version=cli.api.api_version,
                        labels={'test': '1'},
                        image='alpine:3.5',
                        command=['sh', '-c', 'echo asd']
                    ), name='test_simple'
                )

                cli.api.start(c['Id'])

                print(cli.api.inspect_container(c['Id'])['State']['Status'])  # running
                print(run_shell('docker', 'inspect', 'test_simple')['State']['Status'])  # running
                sleep(5)
                print(run_shell('docker', 'inspect', 'test_simple')['State']['Status'])  # exited

                for log in cli.api.attach(c['Id'], stream=True, logs=True):
                    print(log)  # b'asd\n'

                # todo this line is never reached at all
        finally:
            try:
                with closing(DockerClient('unix:///var/run/docker.sock')) as cli:
                    cli.api.remove_container('test_simple')
            except:
                pass

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the inline tests with Docker-py 3.4.1, focusing on c.attach(stream=True, logs=True) and cli.api.attach after the container exits. Trace the attach entry points and verify that iteration terminates after the final log, then rerun both test cases to confirm cleanup still works.

Written by the indexing model from the issue text.

Assessment

Tech stack
docker, python
Domain
api, devops
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.