Skip to content

Commit 059d8ea

Browse files
mayeutjoerick
andauthored
feat: drop EOL manylinux images (#2316)
* drop EOL manylinux images * chore: use multi-arch manylinux images as a source for image tag Using multi-arch images directly messes with parallel tests for now. Using them as a source for image tag ensures that all architecture specific tags are pointing to the same tag for a given manylinux / musllinux policy. * Apply review suggestion Co-authored-by: Joe Rickerby <[email protected]> --------- Co-authored-by: Joe Rickerby <[email protected]>
1 parent 3b9c8d4 commit 059d8ea

16 files changed

+128
-252
lines changed

bin/update_docker.py

Lines changed: 34 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -14,74 +14,45 @@
1414
@dataclass(frozen=True)
1515
class Image:
1616
manylinux_version: str
17-
platform: str
17+
platforms: list[str]
1818
image_name: str
19-
tag: str | None # Set this to pin the image
19+
tag: str | None = None # Set this to pin the image
20+
use_platform_suffix: bool = False
2021

2122

2223
class PyPAImage(Image):
23-
def __init__(self, manylinux_version: str, platform: str, tag: str | None):
24-
platform_no_pypy = platform.removeprefix("pypy_")
25-
image_name = f"quay.io/pypa/{manylinux_version}_{platform_no_pypy}"
26-
super().__init__(manylinux_version, platform, image_name, tag)
24+
def __init__(self, manylinux_version: str, platforms: list[str], tag: str | None = None):
25+
image_name = f"quay.io/pypa/{manylinux_version}"
26+
super().__init__(manylinux_version, platforms, image_name, tag, True)
2727

2828

2929
images = [
30-
# manylinux1 images, EOL -> use tag
31-
PyPAImage("manylinux1", "x86_64", "2024-04-29-76807b8"),
32-
PyPAImage("manylinux1", "i686", "2024-04-29-76807b8"),
33-
# manylinux2010 images, EOL -> use tag
34-
PyPAImage("manylinux2010", "x86_64", "2022-08-05-4535177"),
35-
PyPAImage("manylinux2010", "i686", "2022-08-05-4535177"),
36-
PyPAImage("manylinux2010", "pypy_x86_64", "2022-08-05-4535177"),
37-
PyPAImage("manylinux2010", "pypy_i686", "2022-08-05-4535177"),
3830
# manylinux2014 images
39-
PyPAImage("manylinux2014", "x86_64", None),
40-
PyPAImage("manylinux2014", "i686", None),
41-
PyPAImage("manylinux2014", "aarch64", None),
42-
PyPAImage("manylinux2014", "ppc64le", None),
43-
PyPAImage("manylinux2014", "s390x", None),
44-
PyPAImage("manylinux2014", "pypy_x86_64", None),
45-
PyPAImage("manylinux2014", "pypy_i686", None),
46-
PyPAImage("manylinux2014", "pypy_aarch64", None),
47-
# manylinux_2_24 images, EOL -> use tag
48-
PyPAImage("manylinux_2_24", "x86_64", "2022-12-26-0d38463"),
49-
PyPAImage("manylinux_2_24", "i686", "2022-12-26-0d38463"),
50-
PyPAImage("manylinux_2_24", "aarch64", "2022-12-26-0d38463"),
51-
PyPAImage("manylinux_2_24", "ppc64le", "2022-12-26-0d38463"),
52-
PyPAImage("manylinux_2_24", "s390x", "2022-12-26-0d38463"),
53-
PyPAImage("manylinux_2_24", "pypy_x86_64", "2022-12-26-0d38463"),
54-
PyPAImage("manylinux_2_24", "pypy_i686", "2022-12-26-0d38463"),
55-
PyPAImage("manylinux_2_24", "pypy_aarch64", "2022-12-26-0d38463"),
31+
PyPAImage(
32+
"manylinux2014",
33+
[
34+
"x86_64",
35+
"i686",
36+
"aarch64",
37+
"ppc64le",
38+
"s390x",
39+
"pypy_x86_64",
40+
"pypy_i686",
41+
"pypy_aarch64",
42+
],
43+
),
5644
# manylinux_2_28 images
57-
PyPAImage("manylinux_2_28", "x86_64", None),
58-
PyPAImage("manylinux_2_28", "aarch64", None),
59-
PyPAImage("manylinux_2_28", "ppc64le", None),
60-
PyPAImage("manylinux_2_28", "s390x", None),
61-
PyPAImage("manylinux_2_28", "pypy_x86_64", None),
62-
PyPAImage("manylinux_2_28", "pypy_aarch64", None),
45+
PyPAImage(
46+
"manylinux_2_28", ["x86_64", "aarch64", "ppc64le", "s390x", "pypy_x86_64", "pypy_aarch64"]
47+
),
6348
# manylinux_2_31 images
64-
PyPAImage("manylinux_2_31", "armv7l", None),
49+
PyPAImage("manylinux_2_31", ["armv7l"]),
6550
# manylinux_2_34 images
66-
PyPAImage("manylinux_2_34", "x86_64", None),
67-
PyPAImage("manylinux_2_34", "aarch64", None),
68-
PyPAImage("manylinux_2_34", "ppc64le", None),
69-
PyPAImage("manylinux_2_34", "s390x", None),
70-
PyPAImage("manylinux_2_34", "pypy_x86_64", None),
71-
PyPAImage("manylinux_2_34", "pypy_aarch64", None),
72-
# musllinux_1_1 images, EOL -> use tag
73-
PyPAImage("musllinux_1_1", "x86_64", "2024.10.26-1"),
74-
PyPAImage("musllinux_1_1", "i686", "2024.10.26-1"),
75-
PyPAImage("musllinux_1_1", "aarch64", "2024.10.26-1"),
76-
PyPAImage("musllinux_1_1", "ppc64le", "2024.10.26-1"),
77-
PyPAImage("musllinux_1_1", "s390x", "2024.10.26-1"),
51+
PyPAImage(
52+
"manylinux_2_34", ["x86_64", "aarch64", "ppc64le", "s390x", "pypy_x86_64", "pypy_aarch64"]
53+
),
7854
# musllinux_1_2 images
79-
PyPAImage("musllinux_1_2", "x86_64", None),
80-
PyPAImage("musllinux_1_2", "i686", None),
81-
PyPAImage("musllinux_1_2", "aarch64", None),
82-
PyPAImage("musllinux_1_2", "ppc64le", None),
83-
PyPAImage("musllinux_1_2", "s390x", None),
84-
PyPAImage("musllinux_1_2", "armv7l", None),
55+
PyPAImage("musllinux_1_2", ["x86_64", "i686", "aarch64", "ppc64le", "s390x", "armv7l"]),
8556
]
8657

8758
config = configparser.ConfigParser()
@@ -137,10 +108,13 @@ def __init__(self, manylinux_version: str, platform: str, tag: str | None):
137108
)
138109
tag_name = pinned_tag["name"]
139110

140-
if not config.has_section(image.platform):
141-
config[image.platform] = {}
142-
143-
config[image.platform][image.manylinux_version] = f"{image.image_name}:{tag_name}"
111+
for platform in image.platforms:
112+
if not config.has_section(platform):
113+
config[platform] = {}
114+
suffix = ""
115+
if image.use_platform_suffix:
116+
suffix = f"_{platform.removeprefix('pypy_')}"
117+
config[platform][image.manylinux_version] = f"{image.image_name}{suffix}:{tag_name}"
144118

145119
with open(RESOURCES / "pinned_docker_images.cfg", "w") as f:
146120
config.write(f)

cibuildwheel/options.py

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -673,10 +673,18 @@ def globals(self) -> GlobalOptions:
673673
)
674674

675675
def _check_pinned_image(self, value: str, pinned_images: Mapping[str, str]) -> None:
676-
if (
677-
value in {"manylinux1", "manylinux2010", "manylinux_2_24", "musllinux_1_1"}
678-
and value not in self._image_warnings
679-
):
676+
error_set = {"manylinux1", "manylinux2010", "manylinux_2_24", "musllinux_1_1"}
677+
warning_set: set[str] = set()
678+
679+
if value in error_set:
680+
msg = (
681+
f"cibuildwheel 3.x does not support the image {value!r}. Either upgrade to a "
682+
"supported image or continue using the image by pinning it directly with"
683+
" its full OCI registry '<name>{:<tag>|@<digest>}'."
684+
)
685+
raise errors.DeprecationError(msg)
686+
687+
if value in warning_set and value not in self._image_warnings:
680688
self._image_warnings.add(value)
681689
msg = (
682690
f"Deprecated image {value!r}. This value will not work"
@@ -783,35 +791,29 @@ def _compute_build_options(self, identifier: str | None) -> BuildOptions:
783791

784792
for build_platform in MANYLINUX_ARCHS:
785793
pinned_images = all_pinned_container_images[build_platform]
786-
787794
config_value = self.reader.get(
788795
f"manylinux-{build_platform}-image", ignore_empty=True
789796
)
790-
797+
self._check_pinned_image(config_value, pinned_images)
791798
if not config_value:
792799
# default to manylinux2014
793800
image = pinned_images["manylinux2014"]
794801
elif config_value in pinned_images:
795-
self._check_pinned_image(config_value, pinned_images)
796802
image = pinned_images[config_value]
797803
else:
798804
image = config_value
799-
800805
manylinux_images[build_platform] = image
801806

802807
for build_platform in MUSLLINUX_ARCHS:
803808
pinned_images = all_pinned_container_images[build_platform]
804-
805809
config_value = self.reader.get(f"musllinux-{build_platform}-image")
806-
810+
self._check_pinned_image(config_value, pinned_images)
807811
if not config_value:
808812
image = pinned_images["musllinux_1_2"]
809813
elif config_value in pinned_images:
810-
self._check_pinned_image(config_value, pinned_images)
811814
image = pinned_images[config_value]
812815
else:
813816
image = config_value
814-
815817
musllinux_images[build_platform] = image
816818

817819
container_engine_str = self.reader.get(

cibuildwheel/resources/pinned_docker_images.cfg

Lines changed: 8 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,41 @@
11
[x86_64]
2-
manylinux1 = quay.io/pypa/manylinux1_x86_64:2024-04-29-76807b8
3-
manylinux2010 = quay.io/pypa/manylinux2010_x86_64:2022-08-05-4535177
42
manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2025.03.15-1
5-
manylinux_2_24 = quay.io/pypa/manylinux_2_24_x86_64:2022-12-26-0d38463
63
manylinux_2_28 = quay.io/pypa/manylinux_2_28_x86_64:2025.03.15-1
74
manylinux_2_34 = quay.io/pypa/manylinux_2_34_x86_64:2025.03.15-1
8-
musllinux_1_1 = quay.io/pypa/musllinux_1_1_x86_64:2024.10.26-1
95
musllinux_1_2 = quay.io/pypa/musllinux_1_2_x86_64:2025.03.15-1
106

117
[i686]
12-
manylinux1 = quay.io/pypa/manylinux1_i686:2024-04-29-76807b8
13-
manylinux2010 = quay.io/pypa/manylinux2010_i686:2022-08-05-4535177
148
manylinux2014 = quay.io/pypa/manylinux2014_i686:2025.03.15-1
15-
manylinux_2_24 = quay.io/pypa/manylinux_2_24_i686:2022-12-26-0d38463
16-
musllinux_1_1 = quay.io/pypa/musllinux_1_1_i686:2024.10.26-1
179
musllinux_1_2 = quay.io/pypa/musllinux_1_2_i686:2025.03.15-1
1810

19-
[pypy_x86_64]
20-
manylinux2010 = quay.io/pypa/manylinux2010_x86_64:2022-08-05-4535177
21-
manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2025.03.15-1
22-
manylinux_2_24 = quay.io/pypa/manylinux_2_24_x86_64:2022-12-26-0d38463
23-
manylinux_2_28 = quay.io/pypa/manylinux_2_28_x86_64:2025.03.15-1
24-
manylinux_2_34 = quay.io/pypa/manylinux_2_34_x86_64:2025.03.15-1
25-
26-
[pypy_i686]
27-
manylinux2010 = quay.io/pypa/manylinux2010_i686:2022-08-05-4535177
28-
manylinux2014 = quay.io/pypa/manylinux2014_i686:2025.03.15-1
29-
manylinux_2_24 = quay.io/pypa/manylinux_2_24_i686:2022-12-26-0d38463
30-
3111
[aarch64]
3212
manylinux2014 = quay.io/pypa/manylinux2014_aarch64:2025.03.15-1
33-
manylinux_2_24 = quay.io/pypa/manylinux_2_24_aarch64:2022-12-26-0d38463
3413
manylinux_2_28 = quay.io/pypa/manylinux_2_28_aarch64:2025.03.15-1
3514
manylinux_2_34 = quay.io/pypa/manylinux_2_34_aarch64:2025.03.15-1
36-
musllinux_1_1 = quay.io/pypa/musllinux_1_1_aarch64:2024.10.26-1
3715
musllinux_1_2 = quay.io/pypa/musllinux_1_2_aarch64:2025.03.15-1
3816

3917
[ppc64le]
4018
manylinux2014 = quay.io/pypa/manylinux2014_ppc64le:2025.03.15-1
41-
manylinux_2_24 = quay.io/pypa/manylinux_2_24_ppc64le:2022-12-26-0d38463
4219
manylinux_2_28 = quay.io/pypa/manylinux_2_28_ppc64le:2025.03.15-1
4320
manylinux_2_34 = quay.io/pypa/manylinux_2_34_ppc64le:2025.03.15-1
44-
musllinux_1_1 = quay.io/pypa/musllinux_1_1_ppc64le:2024.10.26-1
4521
musllinux_1_2 = quay.io/pypa/musllinux_1_2_ppc64le:2025.03.15-1
4622

4723
[s390x]
4824
manylinux2014 = quay.io/pypa/manylinux2014_s390x:2025.03.15-1
49-
manylinux_2_24 = quay.io/pypa/manylinux_2_24_s390x:2022-12-26-0d38463
5025
manylinux_2_28 = quay.io/pypa/manylinux_2_28_s390x:2025.03.15-1
5126
manylinux_2_34 = quay.io/pypa/manylinux_2_34_s390x:2025.03.15-1
52-
musllinux_1_1 = quay.io/pypa/musllinux_1_1_s390x:2024.10.26-1
5327
musllinux_1_2 = quay.io/pypa/musllinux_1_2_s390x:2025.03.15-1
5428

29+
[pypy_x86_64]
30+
manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2025.03.15-1
31+
manylinux_2_28 = quay.io/pypa/manylinux_2_28_x86_64:2025.03.15-1
32+
manylinux_2_34 = quay.io/pypa/manylinux_2_34_x86_64:2025.03.15-1
33+
34+
[pypy_i686]
35+
manylinux2014 = quay.io/pypa/manylinux2014_i686:2025.03.15-1
36+
5537
[pypy_aarch64]
5638
manylinux2014 = quay.io/pypa/manylinux2014_aarch64:2025.03.15-1
57-
manylinux_2_24 = quay.io/pypa/manylinux_2_24_aarch64:2022-12-26-0d38463
5839
manylinux_2_28 = quay.io/pypa/manylinux_2_28_aarch64:2025.03.15-1
5940
manylinux_2_34 = quay.io/pypa/manylinux_2_34_aarch64:2025.03.15-1
6041

docs/cpp_standards.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@ title: Modern C++ standards
77
Building Python wheels with modern C++ standards (C++11 and later) requires a few tricks.
88

99

10-
## manylinux1 and C++14
11-
The past end-of-life `manylinux1` image (based on CentOS 5) contains a version of GCC and libstdc++ that only supports C++11 and earlier standards. There are however ways to compile wheels with the C++14 standard (and later): https://github.com/pypa/manylinux/issues/118
10+
## manylinux2014 and C++20
1211

13-
`manylinux2010` and `manylinux2014` are newer and support all C++ standards (up to C++17).
12+
The past end-of-life `manylinux2014` image (based on CentOS 7) contains a version of GCC and libstdc++ that only supports C++17 and earlier standards.
13+
14+
`manylinux_2_28` are newer and support all C++ standards (up to C++20).
1415

1516
## macOS and deployment target versions
1617

docs/faq.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ title: Tips and tricks
1010

1111
Linux wheels are built in [`manylinux`/`musllinux` containers](https://github.com/pypa/manylinux) to provide binary compatible wheels on Linux, according to [PEP 600](https://www.python.org/dev/peps/pep-0600/) / [PEP 656](https://www.python.org/dev/peps/pep-0656/). Because of this, when building with `cibuildwheel` on Linux, a few things should be taken into account:
1212

13-
- Programs and libraries are not installed on the CI runner host, but rather should be installed inside the container - using `yum` for `manylinux2010` or `manylinux2014`, `apt-get` for `manylinux_2_24`/`manylinux_2_31`, `dnf` for `manylinux_2_28` and `apk` for `musllinux_1_1` or `musllinux_1_2`, or manually. The same goes for environment variables that are potentially needed to customize the wheel building.
13+
- Programs and libraries are not installed on the CI runner host, but rather should be installed inside the container - using `yum` for `manylinux2014`, `apt-get` for `manylinux_2_31`, `dnf` for `manylinux_2_28` and `apk` for `musllinux_1_1` or `musllinux_1_2`, or manually. The same goes for environment variables that are potentially needed to customize the wheel building.
1414

1515
`cibuildwheel` supports this by providing the [`CIBW_ENVIRONMENT`](options.md#environment) and [`CIBW_BEFORE_ALL`](options.md#before-all) options to setup the build environment inside the running container.
1616

0 commit comments

Comments
 (0)