mirror of
https://github.com/Tecnativa/docker-socket-proxy
synced 2024-11-27 10:28:18 +00:00
92 lines
2.8 KiB
Python
92 lines
2.8 KiB
Python
import json
|
|
import logging
|
|
import time
|
|
from contextlib import contextmanager
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
from plumbum import local
|
|
from plumbum.cmd import docker
|
|
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
|
|
def pytest_addoption(parser):
|
|
"""Allow prebuilding image for local testing."""
|
|
parser.addoption(
|
|
"--prebuild", action="store_true", help="Build local image before testing"
|
|
)
|
|
parser.addoption(
|
|
"--image",
|
|
action="store",
|
|
default="test:docker-socket-proxy",
|
|
help="Specify testing image name",
|
|
)
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
def image(request):
|
|
"""Get image name. Builds it if needed."""
|
|
image = request.config.getoption("--image")
|
|
if request.config.getoption("--prebuild"):
|
|
build = docker["image", "build", "-t", image, Path(__file__).parent.parent]
|
|
retcode, stdout, stderr = build.run()
|
|
_logger.log(
|
|
# Pytest prints warnings if a test fails, so this is a warning if
|
|
# the build succeeded, to allow debugging the build logs
|
|
logging.ERROR if retcode else logging.WARNING,
|
|
"Build logs for COMMAND: %s\nEXIT CODE:%d\nSTDOUT:%s\nSTDERR:%s",
|
|
build.bound_command(),
|
|
retcode,
|
|
stdout,
|
|
stderr,
|
|
)
|
|
assert not retcode, "Image build failed"
|
|
return image
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
def proxy_factory(image):
|
|
"""A context manager that starts the proxy with the specified env.
|
|
|
|
While inside the block, `$DOCKER_HOST` will be modified to talk to the proxy
|
|
instead of the raw docker socket.
|
|
"""
|
|
|
|
@contextmanager
|
|
def _proxy(**env_vars):
|
|
container_id = None
|
|
env_list = [f"--env={key}={value}" for key, value in env_vars.items()]
|
|
_logger.info(f"Starting {image} container with: {env_list}")
|
|
try:
|
|
container_id = docker(
|
|
"container",
|
|
"run",
|
|
"--detach",
|
|
"--privileged",
|
|
"--publish=2375",
|
|
"--volume=/var/run/docker.sock:/var/run/docker.sock",
|
|
*env_list,
|
|
image,
|
|
).strip()
|
|
time.sleep(0.5)
|
|
container_data = json.loads(
|
|
docker("container", "inspect", container_id.strip())
|
|
)
|
|
socket_port = container_data[0]["NetworkSettings"]["Ports"]["2375/tcp"][0][
|
|
"HostPort"
|
|
]
|
|
with local.env(DOCKER_HOST=f"tcp://localhost:{socket_port}"):
|
|
yield container_id
|
|
finally:
|
|
if container_id:
|
|
_logger.info(f"Removing {container_id}...")
|
|
docker(
|
|
"container",
|
|
"rm",
|
|
"-f",
|
|
container_id,
|
|
)
|
|
|
|
return _proxy
|