Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Container is not running with host network #44

Open
nandamller opened this issue Jun 15, 2022 · 2 comments
Open

Container is not running with host network #44

nandamller opened this issue Jun 15, 2022 · 2 comments

Comments

@nandamller
Copy link

nandamller commented Jun 15, 2022

Hi, I am trying to use your library. However, I can't get it to work with containers on network = 'host'

Here is my minimalist test.py:

import pytest
import os

from http.client import HTTPConnection
from pytest_docker_tools import build, container

app_image = build(path=os.path.join(os.path.dirname(__file__), 'app'),)
app = container(image='{app_image.id}', network='host')

def test_app(app):
    assert app.status == 'running'

@pytest.fixture
def app_connection(app):
    return HTTPConnection('127.0.0.1:8080')

def test_app_connection(app_connection):
    app_connection.request('GET', '/')
    response = app_connection.getresponse()
    
    assert response.status == 200

My minimalist app.py:

import logging
from flask import Flask

logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)

app = Flask(__name__)

@app.route("/", methods=['GET'])
def main():
    logger.info(f"\nIt's here!\n")

    return 'ok'

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=8080, debug=True)

My Dockerfile:

FROM python:3.8.12-bullseye

COPY . ./python

WORKDIR python

RUN pip install -r requirements.txt

CMD ["python3", "app.py" ]

The requirements.txt
Flask==2.0.2

Versions:
Python 3.9.7, pytest-7.1.2, pluggy-1.0.0
plugins: docker-tools-3.1.3, docker-0.12.0

And this is the error I'm getting:

___________________________________________________ ERROR at setup of test_app ____________________________________________________
request = <SubRequest 'app' for <Function test_app>>, docker_client = <docker.client.DockerClient object at 0x7ff643dbd2b0>
wrapper_class = <class 'pytest_docker_tools.wrappers.container.Container'>
kwargs = {'detach': True, 'image': 'sha256:dc01bb5db190457b853253c7e117799f4190a133e4f30ba3136398ca377e2540', 'labels': {'creat...pytest-docker-tools.signature': 'f2725c8390dd6369525756e85c5595fd6eec803dc9867a90aaf8174c435bac96'}, 'network': 'host'}
signature = 'f2725c8390dd6369525756e85c5595fd6eec803dc9867a90aaf8174c435bac96', timeout = 30
container = <pytest_docker_tools.wrappers.container.Container object at 0x7ff643dbd850>

    @fixture_factory()
    def container(request, docker_client, wrapper_class, **kwargs):
        """ Docker container: image={image} """
    
        wrapper_class = wrapper_class or Container
    
        kwargs.update({"detach": True})
        set_reusable_labels(kwargs, request)
    
        signature = hash_params(kwargs)
        set_signature(kwargs, signature)
    
        if request.config.option.reuse_containers:
            if "name" not in kwargs.keys():
                pytest.fail(
                    "Tried to use '--reuse-containers' command line argument without "
                    "setting 'name' attribute on container"
                )
    
            name = kwargs["name"]
    
            try:
                current = docker_client.containers.get(name)
            except NotFound:
                pass
            else:
                # Found a container with the right name, but it doesn't have pytest-docker-tools labels
                # We shouldn't just clobber it, its not ours. Bail out.
                if not is_reusable_container(current):
                    pytest.fail(
                        f"Tried to reuse {name} but it does not appear to be a reusable container"
                    )
    
                # It's ours, and its not stale. Reuse it!
                if check_signature(current.labels, signature):
                    return wrapper_class(current)
    
                # It's ours and it is stale. Clobber it.
                print(f"Removing stale reusable container: {name}")
                current.remove(force=True)
    
        timeout = kwargs.pop("timeout", 30)
    
        raw_container = docker_client.containers.run(**kwargs)
        if not request.config.option.reuse_containers:
            request.addfinalizer(
                lambda: raw_container.remove(force=True) and raw_container.wait(timeout=10)
            )
    
        container = wrapper_class(raw_container)
    
        try:
>           wait_for_callable("Waiting for container to be ready", container.ready, timeout)

../.local/lib/python3.9/site-packages/pytest_docker_tools/factories/container.py:69: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

message = 'Waiting for container to be ready'
func = <bound method Container.ready of <pytest_docker_tools.wrappers.container.Container object at 0x7ff643dbd850>>, timeout = 30

    def wait_for_callable(message: str, func: Callable, timeout: int = 30) -> None:
        """
        Runs a callable once a second until it returns True or we hit the timeout.
        """
        sys.stdout.write(message)
        try:
            for i in range(timeout):
                sys.stdout.write(".")
                sys.stdout.flush()
    
                if func():
                    return
    
                time.sleep(1)
        finally:
            sys.stdout.write("\n")
    
>       raise TimeoutError(f"Timeout of {timeout}s exceeded")
E       pytest_docker_tools.exceptions.TimeoutError: Timeout of 30s exceeded

../.local/lib/python3.9/site-packages/pytest_docker_tools/utils.py:37: TimeoutError

During handling of the above exception, another exception occurred:

request = <SubRequest 'app' for <Function test_app>>, docker_client = <docker.client.DockerClient object at 0x7ff643dbd2b0>
wrapper_class = <class 'pytest_docker_tools.wrappers.container.Container'>
kwargs = {'detach': True, 'image': 'sha256:dc01bb5db190457b853253c7e117799f4190a133e4f30ba3136398ca377e2540', 'labels': {'creat...pytest-docker-tools.signature': 'f2725c8390dd6369525756e85c5595fd6eec803dc9867a90aaf8174c435bac96'}, 'network': 'host'}
signature = 'f2725c8390dd6369525756e85c5595fd6eec803dc9867a90aaf8174c435bac96', timeout = 30
container = <pytest_docker_tools.wrappers.container.Container object at 0x7ff643dbd850>

    @fixture_factory()
    def container(request, docker_client, wrapper_class, **kwargs):
        """ Docker container: image={image} """
    
        wrapper_class = wrapper_class or Container
    
        kwargs.update({"detach": True})
        set_reusable_labels(kwargs, request)
    
        signature = hash_params(kwargs)
        set_signature(kwargs, signature)
    
        if request.config.option.reuse_containers:
            if "name" not in kwargs.keys():
                pytest.fail(
                    "Tried to use '--reuse-containers' command line argument without "
                    "setting 'name' attribute on container"
                )
    
            name = kwargs["name"]
    
            try:
                current = docker_client.containers.get(name)
            except NotFound:
                pass
            else:
                # Found a container with the right name, but it doesn't have pytest-docker-tools labels
                # We shouldn't just clobber it, its not ours. Bail out.
                if not is_reusable_container(current):
                    pytest.fail(
                        f"Tried to reuse {name} but it does not appear to be a reusable container"
                    )
    
                # It's ours, and its not stale. Reuse it!
                if check_signature(current.labels, signature):
                    return wrapper_class(current)
    
                # It's ours and it is stale. Clobber it.
                print(f"Removing stale reusable container: {name}")
                current.remove(force=True)
    
        timeout = kwargs.pop("timeout", 30)
    
        raw_container = docker_client.containers.run(**kwargs)
        if not request.config.option.reuse_containers:
            request.addfinalizer(
                lambda: raw_container.remove(force=True) and raw_container.wait(timeout=10)
            )
    
        container = wrapper_class(raw_container)
    
        try:
            wait_for_callable("Waiting for container to be ready", container.ready, timeout)
        except TimeoutError:
>           raise ContainerNotReady(
                container, "Timeout while waiting for container to be ready"
            )
E           pytest_docker_tools.exceptions.ContainerNotReady: Timeout while waiting for container to be ready

../.local/lib/python3.9/site-packages/pytest_docker_tools/factories/container.py:71: ContainerNotReady
------------------------------------------------------ Captured stdout setup ------------------------------------------------------
Building /home/fernanda/conectionTest/app.....................
Waiting for container to be ready..............................
------------------------------------------------------- nostalgic_goldberg --------------------------------------------------------
 * Serving Flask app 'app' (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: on
INFO:werkzeug: * Running on all addresses (0.0.0.0)
   WARNING: This is a development server. Do not use it in a production deployment.
 * Running on http://127.0.0.1:8080
 * Running on http://192.168.2.109:8080 (Press CTRL+C to quit)
INFO:werkzeug: * Restarting with stat
WARNING:werkzeug: * Debugger is active!
INFO:werkzeug: * Debugger PIN: 982-840-186
______________________________________________ ERROR at setup of test_app_connection ______________________________________________

request = <SubRequest 'app' for <Function test_app_connection>>
docker_client = <docker.client.DockerClient object at 0x7ff643dbd2b0>
wrapper_class = <class 'pytest_docker_tools.wrappers.container.Container'>
kwargs = {'detach': True, 'image': 'sha256:dc01bb5db190457b853253c7e117799f4190a133e4f30ba3136398ca377e2540', 'labels': {'creat...pytest-docker-tools.signature': 'f2725c8390dd6369525756e85c5595fd6eec803dc9867a90aaf8174c435bac96'}, 'network': 'host'}
signature = 'f2725c8390dd6369525756e85c5595fd6eec803dc9867a90aaf8174c435bac96', timeout = 30
container = <pytest_docker_tools.wrappers.container.Container object at 0x7ff643d71970>

    @fixture_factory()
    def container(request, docker_client, wrapper_class, **kwargs):
        """ Docker container: image={image} """
    
        wrapper_class = wrapper_class or Container
    
        kwargs.update({"detach": True})
        set_reusable_labels(kwargs, request)
    
        signature = hash_params(kwargs)
        set_signature(kwargs, signature)
    
        if request.config.option.reuse_containers:
            if "name" not in kwargs.keys():
                pytest.fail(
                    "Tried to use '--reuse-containers' command line argument without "
                    "setting 'name' attribute on container"
                )
    
            name = kwargs["name"]
    
            try:
                current = docker_client.containers.get(name)
            except NotFound:
                pass
            else:
                # Found a container with the right name, but it doesn't have pytest-docker-tools labels
                # We shouldn't just clobber it, its not ours. Bail out.
                if not is_reusable_container(current):
                    pytest.fail(
                        f"Tried to reuse {name} but it does not appear to be a reusable container"
                    )
    
                # It's ours, and its not stale. Reuse it!
                if check_signature(current.labels, signature):
                    return wrapper_class(current)
    
                # It's ours and it is stale. Clobber it.
                print(f"Removing stale reusable container: {name}")
                current.remove(force=True)
    
        timeout = kwargs.pop("timeout", 30)
    
        raw_container = docker_client.containers.run(**kwargs)
        if not request.config.option.reuse_containers:
            request.addfinalizer(
                lambda: raw_container.remove(force=True) and raw_container.wait(timeout=10)
            )
    
        container = wrapper_class(raw_container)
    
        try:
>           wait_for_callable("Waiting for container to be ready", container.ready, timeout)

../.local/lib/python3.9/site-packages/pytest_docker_tools/factories/container.py:69: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

message = 'Waiting for container to be ready'
func = <bound method Container.ready of <pytest_docker_tools.wrappers.container.Container object at 0x7ff643d71970>>, timeout = 30

    def wait_for_callable(message: str, func: Callable, timeout: int = 30) -> None:
        """
        Runs a callable once a second until it returns True or we hit the timeout.
        """
        sys.stdout.write(message)
        try:
            for i in range(timeout):
                sys.stdout.write(".")
                sys.stdout.flush()
    
                if func():
                    return
    
                time.sleep(1)
        finally:
            sys.stdout.write("\n")
    
>       raise TimeoutError(f"Timeout of {timeout}s exceeded")
E       pytest_docker_tools.exceptions.TimeoutError: Timeout of 30s exceeded

../.local/lib/python3.9/site-packages/pytest_docker_tools/utils.py:37: TimeoutError

During handling of the above exception, another exception occurred:

request = <SubRequest 'app' for <Function test_app_connection>>
docker_client = <docker.client.DockerClient object at 0x7ff643dbd2b0>
wrapper_class = <class 'pytest_docker_tools.wrappers.container.Container'>
kwargs = {'detach': True, 'image': 'sha256:dc01bb5db190457b853253c7e117799f4190a133e4f30ba3136398ca377e2540', 'labels': {'creat...pytest-docker-tools.signature': 'f2725c8390dd6369525756e85c5595fd6eec803dc9867a90aaf8174c435bac96'}, 'network': 'host'}
signature = 'f2725c8390dd6369525756e85c5595fd6eec803dc9867a90aaf8174c435bac96', timeout = 30
container = <pytest_docker_tools.wrappers.container.Container object at 0x7ff643d71970>

    @fixture_factory()
    def container(request, docker_client, wrapper_class, **kwargs):
        """ Docker container: image={image} """
    
        wrapper_class = wrapper_class or Container
    
        kwargs.update({"detach": True})
        set_reusable_labels(kwargs, request)
    
        signature = hash_params(kwargs)
        set_signature(kwargs, signature)
    
        if request.config.option.reuse_containers:
            if "name" not in kwargs.keys():
                pytest.fail(
                    "Tried to use '--reuse-containers' command line argument without "
                    "setting 'name' attribute on container"
                )
    
            name = kwargs["name"]
    
            try:
                current = docker_client.containers.get(name)
            except NotFound:
                pass
            else:
                # Found a container with the right name, but it doesn't have pytest-docker-tools labels
                # We shouldn't just clobber it, its not ours. Bail out.
                if not is_reusable_container(current):
                    pytest.fail(
                        f"Tried to reuse {name} but it does not appear to be a reusable container"
                    )
    
                # It's ours, and its not stale. Reuse it!
                if check_signature(current.labels, signature):
                    return wrapper_class(current)
    
                # It's ours and it is stale. Clobber it.
                print(f"Removing stale reusable container: {name}")
                current.remove(force=True)
    
        timeout = kwargs.pop("timeout", 30)
    
        raw_container = docker_client.containers.run(**kwargs)
        if not request.config.option.reuse_containers:
            request.addfinalizer(
                lambda: raw_container.remove(force=True) and raw_container.wait(timeout=10)
            )
    
        container = wrapper_class(raw_container)
    
        try:
            wait_for_callable("Waiting for container to be ready", container.ready, timeout)
        except TimeoutError:
>           raise ContainerNotReady(
                container, "Timeout while waiting for container to be ready"
            )
E           pytest_docker_tools.exceptions.ContainerNotReady: Timeout while waiting for container to be ready

../.local/lib/python3.9/site-packages/pytest_docker_tools/factories/container.py:71: ContainerNotReady
------------------------------------------------------ Captured stdout setup ------------------------------------------------------
Waiting for container to be ready..............................
---------------------------------------------------------- angry_volhard ----------------------------------------------------------
 * Serving Flask app 'app' (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: on
INFO:werkzeug: * Running on all addresses (0.0.0.0)
   WARNING: This is a development server. Do not use it in a production deployment.
 * Running on http://127.0.0.1:8080
 * Running on http://192.168.2.109:8080 (Press CTRL+C to quit)
INFO:werkzeug: * Restarting with stat
WARNING:werkzeug: * Debugger is active!
INFO:werkzeug: * Debugger PIN: 982-840-186
===================================================== short test summary info =====================================================
ERROR test.py::test_app - pytest_docker_tools.exceptions.ContainerNotReady: Timeout while waiting for container to be ready
ERROR test.py::test_app_connection - pytest_docker_tools.exceptions.ContainerNotReady: Timeout while waiting for container to be...

What am I doing wrong?

@alpex8
Copy link
Contributor

alpex8 commented Jun 16, 2022

AFAIK running containers in host network mode currently is not supported. I was trying to do the same a couple of months ago. I ened up starting to hack the plugin to integrate proper support. However this wasn`t strait forward, because other issues showed up on the way that needed to be addressed as well. In the end I was able to continue without using host networking

@Jc2k
Copy link
Owner

Jc2k commented Jun 16, 2022

Have you tried using network_mode="host" instead of network="host"?

Note that I only use this with docker networks myself (so i can use pytest-xdist safely), so you are kinda on your own here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants