Rename DockerContainer -> OCIContainer, and a few other things
OCIContainer.container_engine -> OCIContainer.engine OCIContainer.docker_image -> OCIContainer.image Variables that refer to 'docker_images' have been renamed to 'container_images'
This commit is contained in:
@@ -18,26 +18,23 @@ from .typing import Literal, PathOrStr, PopenBytes
|
||||
ContainerEngine = Literal["docker", "podman"]
|
||||
|
||||
|
||||
class DockerContainer:
|
||||
class OCIContainer:
|
||||
"""
|
||||
An object that represents a running Docker container.
|
||||
An object that represents a running OCI (e.g. Docker) container.
|
||||
|
||||
Intended for use as a context manager e.g.
|
||||
`with DockerContainer(docker_image = 'ubuntu') as docker:`
|
||||
`with OCIContainer(image = 'ubuntu') as docker:`
|
||||
|
||||
A bash shell is running in the remote container. When `call()` is invoked,
|
||||
the command is relayed to the remote shell, and the results are streamed
|
||||
back to cibuildwheel.
|
||||
|
||||
TODO:
|
||||
- [ ] Rename to Container as this now generalizes docker and podman?
|
||||
|
||||
Example:
|
||||
>>> from cibuildwheel.docker_container import * # NOQA
|
||||
>>> from cibuildwheel.options import _get_pinned_docker_images
|
||||
>>> docker_image = _get_pinned_docker_images()['x86_64']['manylinux2014']
|
||||
>>> from cibuildwheel.options import _get_pinned_container_images
|
||||
>>> image = _get_pinned_container_images()['x86_64']['manylinux2014']
|
||||
>>> # Test the default container
|
||||
>>> with DockerContainer(docker_image=docker_image) as self:
|
||||
>>> with OCIContainer(image=image) as self:
|
||||
... self.call(["echo", "hello world"])
|
||||
... self.call(["cat", "/proc/1/cgroup"])
|
||||
... print(self.get_environment())
|
||||
@@ -53,21 +50,21 @@ class DockerContainer:
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
docker_image: str,
|
||||
image: str,
|
||||
simulate_32_bit: bool = False,
|
||||
cwd: Optional[PathOrStr] = None,
|
||||
container_engine: ContainerEngine = "docker",
|
||||
engine: ContainerEngine = "docker",
|
||||
):
|
||||
if not docker_image:
|
||||
if not image:
|
||||
raise ValueError("Must have a non-empty docker image to run.")
|
||||
|
||||
self.docker_image = docker_image
|
||||
self.image = image
|
||||
self.simulate_32_bit = simulate_32_bit
|
||||
self.cwd = cwd
|
||||
self.name: Optional[str] = None
|
||||
self.container_engine = container_engine
|
||||
self.engine = engine
|
||||
|
||||
def __enter__(self) -> "DockerContainer":
|
||||
def __enter__(self) -> "OCIContainer":
|
||||
|
||||
self.name = f"cibuildwheel-{uuid.uuid4()}"
|
||||
|
||||
@@ -83,14 +80,14 @@ class DockerContainer:
|
||||
|
||||
subprocess.run(
|
||||
[
|
||||
self.container_engine,
|
||||
self.engine,
|
||||
"create",
|
||||
"--env=CIBUILDWHEEL",
|
||||
f"--name={self.name}",
|
||||
"--interactive",
|
||||
"--volume=/:/host", # ignored on CircleCI
|
||||
*network_args,
|
||||
self.docker_image,
|
||||
self.image,
|
||||
*shell_args,
|
||||
],
|
||||
check=True,
|
||||
@@ -98,7 +95,7 @@ class DockerContainer:
|
||||
|
||||
self.process = subprocess.Popen(
|
||||
[
|
||||
self.container_engine,
|
||||
self.engine,
|
||||
"start",
|
||||
"--attach",
|
||||
"--interactive",
|
||||
@@ -136,7 +133,7 @@ class DockerContainer:
|
||||
self.bash_stdin.close()
|
||||
self.bash_stdout.close()
|
||||
|
||||
if self.container_engine == "podman":
|
||||
if self.engine == "podman":
|
||||
# This works around what seems to be a race condition in the podman
|
||||
# backend. The full reason is not understood. See PR #966 for a
|
||||
# discussion on possible causes and attempts to remove this line.
|
||||
@@ -146,7 +143,7 @@ class DockerContainer:
|
||||
assert isinstance(self.name, str)
|
||||
|
||||
subprocess.run(
|
||||
[self.container_engine, "rm", "--force", "-v", self.name],
|
||||
[self.engine, "rm", "--force", "-v", self.name],
|
||||
stdout=subprocess.DEVNULL,
|
||||
check=False,
|
||||
)
|
||||
@@ -161,7 +158,7 @@ class DockerContainer:
|
||||
if from_path.is_dir():
|
||||
self.call(["mkdir", "-p", to_path])
|
||||
subprocess.run(
|
||||
f"tar cf - . | {self.container_engine} exec -i {self.name} tar --no-same-owner -xC {shell_quote(to_path)} -f -",
|
||||
f"tar cf - . | {self.engine} exec -i {self.name} tar --no-same-owner -xC {shell_quote(to_path)} -f -",
|
||||
shell=True,
|
||||
check=True,
|
||||
cwd=from_path,
|
||||
@@ -169,7 +166,7 @@ class DockerContainer:
|
||||
else:
|
||||
with subprocess.Popen(
|
||||
[
|
||||
self.container_engine,
|
||||
self.engine,
|
||||
"exec",
|
||||
"-i",
|
||||
str(self.name),
|
||||
@@ -194,10 +191,10 @@ class DockerContainer:
|
||||
# note: we assume from_path is a dir
|
||||
to_path.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
if self.container_engine == "podman":
|
||||
if self.engine == "podman":
|
||||
subprocess.run(
|
||||
[
|
||||
self.container_engine,
|
||||
self.engine,
|
||||
"cp",
|
||||
f"{self.name}:{from_path}/.",
|
||||
str(to_path),
|
||||
@@ -205,10 +202,10 @@ class DockerContainer:
|
||||
check=True,
|
||||
cwd=to_path,
|
||||
)
|
||||
elif self.container_engine == "docker":
|
||||
elif self.engine == "docker":
|
||||
# There is a bug in docker that prevents a simple 'cp' invocation
|
||||
# from working https://github.com/moby/moby/issues/38995
|
||||
command = f"{self.container_engine} exec -i {self.name} tar -cC {shell_quote(from_path)} -f - . | tar -xf -"
|
||||
command = f"{self.engine} exec -i {self.name} tar -cC {shell_quote(from_path)} -f - . | tar -xf -"
|
||||
subprocess.run(
|
||||
command,
|
||||
shell=True,
|
||||
@@ -216,7 +213,7 @@ class DockerContainer:
|
||||
cwd=to_path,
|
||||
)
|
||||
else:
|
||||
raise KeyError(self.container_engine)
|
||||
raise KeyError(self.engine)
|
||||
|
||||
def glob(self, path: PurePosixPath, pattern: str) -> List[PurePosixPath]:
|
||||
glob_pattern = path.joinpath(pattern)
|
||||
@@ -333,10 +330,10 @@ class DockerContainer:
|
||||
return self.call(command, env=environment, capture_output=True)
|
||||
|
||||
def debug_info(self) -> str:
|
||||
if self.container_engine == "podman":
|
||||
command = f"{self.container_engine} info --debug"
|
||||
if self.engine == "podman":
|
||||
command = f"{self.engine} info --debug"
|
||||
else:
|
||||
command = f"{self.container_engine} info"
|
||||
command = f"{self.engine} info"
|
||||
completed = subprocess.run(
|
||||
command,
|
||||
shell=True,
|
||||
|
||||
+13
-11
@@ -5,7 +5,7 @@ from pathlib import Path, PurePath, PurePosixPath
|
||||
from typing import Iterator, List, NamedTuple, Set, Tuple
|
||||
|
||||
from .architecture import Architecture
|
||||
from .docker_container import DockerContainer
|
||||
from .docker_container import OCIContainer
|
||||
from .logger import log
|
||||
from .options import Options
|
||||
from .typing import OrderedDict, PathOrStr, assert_never
|
||||
@@ -33,7 +33,7 @@ class PythonConfiguration(NamedTuple):
|
||||
class BuildStep(NamedTuple):
|
||||
platform_configs: List[PythonConfiguration]
|
||||
platform_tag: str
|
||||
docker_image: str
|
||||
container_image: str
|
||||
|
||||
|
||||
def get_python_configurations(
|
||||
@@ -55,7 +55,7 @@ def get_python_configurations(
|
||||
]
|
||||
|
||||
|
||||
def docker_image_for_python_configuration(config: PythonConfiguration, options: Options) -> str:
|
||||
def container_image_for_python_configuration(config: PythonConfiguration, options: Options) -> str:
|
||||
build_options = options.build_options(config.identifier)
|
||||
# e.g
|
||||
# identifier is 'cp310-manylinux_x86_64'
|
||||
@@ -87,15 +87,17 @@ def get_build_steps(
|
||||
_, platform_tag = config.identifier.split("-", 1)
|
||||
|
||||
before_all = options.build_options(config.identifier).before_all
|
||||
docker_image = docker_image_for_python_configuration(config, options)
|
||||
container_image = container_image_for_python_configuration(config, options)
|
||||
|
||||
step_key = (platform_tag, docker_image, before_all)
|
||||
step_key = (platform_tag, container_image, before_all)
|
||||
|
||||
if step_key in steps:
|
||||
steps[step_key].platform_configs.append(config)
|
||||
else:
|
||||
steps[step_key] = BuildStep(
|
||||
platform_configs=[config], platform_tag=platform_tag, docker_image=docker_image
|
||||
platform_configs=[config],
|
||||
platform_tag=platform_tag,
|
||||
container_image=container_image,
|
||||
)
|
||||
|
||||
yield from steps.values()
|
||||
@@ -105,7 +107,7 @@ def build_on_docker(
|
||||
*,
|
||||
options: Options,
|
||||
platform_configs: List[PythonConfiguration],
|
||||
docker: DockerContainer,
|
||||
docker: OCIContainer,
|
||||
container_project_path: PurePath,
|
||||
container_package_dir: PurePath,
|
||||
) -> None:
|
||||
@@ -357,14 +359,14 @@ def build(options: Options, tmp_path: Path) -> None: # pylint: disable=unused-a
|
||||
try:
|
||||
ids_to_build = [x.identifier for x in build_step.platform_configs]
|
||||
log.step(
|
||||
f"Starting Docker image {build_step.docker_image} for {', '.join(ids_to_build)}..."
|
||||
f"Starting Docker image {build_step.container_image} for {', '.join(ids_to_build)}..."
|
||||
)
|
||||
|
||||
with DockerContainer(
|
||||
docker_image=build_step.docker_image,
|
||||
with OCIContainer(
|
||||
image=build_step.container_image,
|
||||
simulate_32_bit=build_step.platform_tag.endswith("i686"),
|
||||
cwd=container_project_path,
|
||||
container_engine=options.globals.container_engine,
|
||||
engine=options.globals.container_engine,
|
||||
) as docker:
|
||||
|
||||
build_on_docker(
|
||||
|
||||
@@ -485,10 +485,10 @@ class Options:
|
||||
manylinux_images: Dict[str, str] = {}
|
||||
musllinux_images: Dict[str, str] = {}
|
||||
if self.platform == "linux":
|
||||
all_pinned_docker_images = _get_pinned_docker_images()
|
||||
all_pinned_container_images = _get_pinned_container_images()
|
||||
|
||||
for build_platform in MANYLINUX_ARCHS:
|
||||
pinned_images = all_pinned_docker_images[build_platform]
|
||||
pinned_images = all_pinned_container_images[build_platform]
|
||||
|
||||
config_value = self.reader.get(
|
||||
f"manylinux-{build_platform}-image", ignore_empty=True
|
||||
@@ -505,7 +505,7 @@ class Options:
|
||||
manylinux_images[build_platform] = image
|
||||
|
||||
for build_platform in MUSLLINUX_ARCHS:
|
||||
pinned_images = all_pinned_docker_images[build_platform]
|
||||
pinned_images = all_pinned_container_images[build_platform]
|
||||
|
||||
config_value = self.reader.get(f"musllinux-{build_platform}-image")
|
||||
|
||||
@@ -591,7 +591,7 @@ def compute_options(
|
||||
|
||||
|
||||
@functools.lru_cache(maxsize=None)
|
||||
def _get_pinned_docker_images() -> Mapping[str, Mapping[str, str]]:
|
||||
def _get_pinned_container_images() -> Mapping[str, Mapping[str, str]]:
|
||||
"""
|
||||
This looks like a dict of dicts, e.g.
|
||||
{ 'x86_64': {'manylinux1': '...', 'manylinux2010': '...', 'manylinux2014': '...'},
|
||||
@@ -600,10 +600,10 @@ def _get_pinned_docker_images() -> Mapping[str, Mapping[str, str]]:
|
||||
... }
|
||||
"""
|
||||
|
||||
pinned_docker_images_file = resources_dir / "pinned_docker_images.cfg"
|
||||
all_pinned_docker_images = ConfigParser()
|
||||
all_pinned_docker_images.read(pinned_docker_images_file)
|
||||
return all_pinned_docker_images
|
||||
pinned_images_file = resources_dir / "pinned_docker_images.cfg"
|
||||
all_pinned_images = ConfigParser()
|
||||
all_pinned_images.read(pinned_images_file)
|
||||
return all_pinned_images
|
||||
|
||||
|
||||
def deprecated_selectors(name: str, selector: str, *, error: bool = False) -> None:
|
||||
|
||||
Reference in New Issue
Block a user