PEP 571 – Der manylinux2010 Platform Tag
- Autor:
- Mark Williams <mrw at enotuniq.org>, Geoffrey Thomas <geofft at ldpreload.com>, Thomas Kluyver <thomas at kluyver.me.uk>
- BDFL-Delegate:
- Alyssa Coghlan <ncoghlan at gmail.com>
- Discussions-To:
- Distutils-SIG Liste
- Status:
- Abgelöst
- Typ:
- Informational
- Thema:
- Packaging
- Erstellt:
- 05-Feb-2018
- Post-History:
- Ersetzt-Durch:
- 600
- Resolution:
- Distutils-SIG Nachricht
Zusammenfassung
Diese PEP schlägt die Erstellung eines manylinux2010 Plattform-Tags vor, um den von PEP 513 eingeführten manylinux1-Tag abzulösen. Sie schlägt außerdem vor, dass PyPI und pip beide aktualisiert werden, um das Hochladen, Herunterladen und Installieren von manylinux2010-Distributionen auf kompatiblen Plattformen zu unterstützen.
Begründung
Getreu seinem Namen hat der manylinux1-Plattform-Tag die Installation von binären Erweiterungsmodulen auf vielen Linux-Systemen zur Realität werden lassen. Bibliotheken wie cryptography [2] und numpy [3] sind für Python-Entwickler zugänglicher, da ihre Installation auf gängigen Architekturen nicht mehr von fragilen Entwicklungsumgebungen und Build-Toolchains abhängt.
manylinux1 Wheels erreichen ihre Portabilität, indem sie es den enthaltenen Erweiterungsmodulen erlauben, sich nur gegen eine kleine Menge von System-Shared-Libraries zu linken, die versionierte Symbole exportieren, die alt genug sind, um von Abwärtskompatibilitätsrichtlinien zu profitieren. Erweiterungsmodule in einem manylinux1 Wheel, die sich z.B. auf glibc stützen, müssen gegen Version 2.5 oder früher kompiliert werden; sie können dann auf Systemen ausgeführt werden, die neuere glibc-Versionen bereitstellen, die die erforderlichen Symbole noch unter Version 2.5 exportieren.
PEP 513 bezog seine Whitelist von Shared-Libraries und deren Symbolversionen aus CentOS 5.11, der ältesten unterstützten CentOS-Version zum Zeitpunkt der Erstellung. Leider erreichte CentOS 5.11 sein End-of-Life am 31. März 2017 mit einer klaren Warnung vor seiner weiteren Nutzung. [4] Es werden keine weiteren Updates, wie z.B. Sicherheitspatches, zur Verfügung gestellt. Das bedeutet, dass seine Pakete in veralteten Versionen verbleiben, was die Bemühungen von Python-Software-Packern, die das manylinux1 Docker-Image verwenden, behindert.
CentOS 6 ist nun die älteste unterstützte CentOS-Version und erhält Wartungsaktualisierungen bis zum 30. November 2020. [5] Wir schlagen vor, dass ein neuer Plattform-Tag im PEP 425-Stil namens manylinux2010 von CentOS 6 abgeleitet wird und dass die manylinux Toolchain, PyPI und pip aktualisiert werden, um ihn zu unterstützen.
Dies wurde ursprünglich als manylinux2 vorgeschlagen, aber die Versionierung wurde auf die Verwendung von Kalenderjahren (auch bekannt als CalVer [22]) geändert. Dies erleichtert die Definition zukünftiger manylinux-Tags in beliebiger Reihenfolge: Zum Beispiel kann ein hypothetischer manylinux2017-Standard über eine neue PEP vor manylinux2014 definiert werden, oder ein manylinux2007-Standard, der sich an Systeme richtet, die älter als diese PEP, aber neuer als manylinux1 sind.
Die Kalender-Versionierung gibt auch eine grobe Vorstellung davon, welche Linux-Distribution-Versionen welche Tags unterstützen: manylinux2010 funktioniert auf den meisten seit 2010 veröffentlichten Distributionen. Dies ist jedoch nur eine Annäherung: Die tatsächlichen Kompatibilitätsregeln sind unten definiert, und einige neuere Distributionen erfüllen sie möglicherweise nicht.
Die manylinux2010 Richtlinie
Die folgenden Kriterien bestimmen die Berechtigung eines linux-Wheels für den manylinux2010-Tag
- Das Wheel darf nur Binärdateien und Shared Objects enthalten, die für eine der beiden von CentOS 6 unterstützten Architekturen kompiliert wurden: x86_64 oder i686. [5]
- Die Binärdateien oder Shared Objects des Wheels dürfen sich nicht gegen extern bereitgestellte Bibliotheken linken, außer gegen die in der folgenden Whitelist
libgcc_s.so.1 libstdc++.so.6 libm.so.6 libdl.so.2 librt.so.1 libc.so.6 libnsl.so.1 libutil.so.1 libpthread.so.0 libresolv.so.2 libX11.so.6 libXext.so.6 libXrender.so.1 libICE.so.6 libSM.so.6 libGL.so.1 libgobject-2.0.so.0 libgthread-2.0.so.0 libglib-2.0.so.0
Diese Liste ist identisch mit den für
manylinux1gewhitelisteten extern bereitgestellten Bibliotheken, abzüglichlibncursesw.so.5undlibpanelw.so.5. [7]libpythonX.Ybleibt aus denselben Gründen, die in PEP 513 dargelegt sind, von der Aufnahme ausgeschlossen.libcrypt.so.1wurde nach der Veröffentlichung von Fedora 30 mitlibcrypt.so.2stattdessen rückwirkend von der Whitelist entfernt.Auf Debian-basierten Systemen werden diese Bibliotheken von den Paketen bereitgestellt
Paket Bibliotheken libc6 libdl.so.2, libresolv.so.2, librt.so.1, libc.so.6, libpthread.so.0, libm.so.6, libutil.so.1, libnsl.so.1 libgcc1 libgcc_s.so.1 libgl1 libGL.so.1 libglib2.0-0 libgobject-2.0.so.0, libgthread-2.0.so.0, libglib-2.0.so.0 libice6 libICE.so.6 libsm6 libSM.so.6 libstdc++6 libstdc++.so.6 libx11-6 libX11.so.6 libxext6 libXext.so.6 libxrender1 libXrender.so.1 Auf RPM-basierten Systemen werden diese von diesen Paketen bereitgestellt
Paket Bibliotheken glib2 libglib-2.0.so.0, libgthread-2.0.so.0, libgobject-2.0.so.0 glibc libresolv.so.2, libutil.so.1, libnsl.so.1, librt.so.1, libpthread.so.0, libdl.so.2, libm.so.6, libc.so.6 libICE libICE.so.6 libX11 libX11.so.6 libXext libXext.so.6 libXrender libXrender.so.1 libgcc libgcc_s.so.1 libstdc++ libstdc++.so.6 mesa libGL.so.1 - Wenn das Wheel Binärdateien oder Shared Objects enthält, die gegen gewhitelistete Bibliotheken gelinkt sind, die auch versionierte Symbole exportieren, dürfen diese nur von den folgenden maximalen Versionen abhängen
GLIBC_2.12 CXXABI_1.3.3 GLIBCXX_3.4.13 GCC_4.5.0
Zum Beispiel dürfen
manylinux2010Wheels Binärartefakte enthalten, dieglibc-Symbole der VersionGLIBC_2.4benötigen, da dies eine frühere Version als das Maximum vonGLIBC_2.12ist. - Wenn ein Wheel für eine beliebige Version von CPython 2 oder CPython Versionen 3.0 bis einschließlich 3.2 gebaut wird, *muss* es ein CPython ABI-Tag enthalten, das seine Unicode-ABI angibt. Ein gegen Python 2 gebautes
manylinux2010-Wheel muss also entweder das Tagcpy27mu, das angibt, dass es gegen einen Interpreter mit der UCS-4-ABI gebaut wurde, oder das Tagcpy27m, das einen Interpreter mit der UCS-2-ABI angibt, enthalten. (PEP 3149, [9]) - Ein Wheel darf das Symbol
PyFPE_jbuf*nicht* benötigen. Dies wird erreicht, indem es gegen eine Python-Version kompiliert wird, die *ohne* das--with-fpectlconfigureFlag kompiliert wurde.
Kompilierung konformer Wheels
Wie manylinux1 fügt das Werkzeug auditwheel manylinux2010-Plattform-Tags zu linux-Wheels hinzu, die von pip wheel oder bdist_wheel in einem manylinux2010 Docker-Container gebaut werden.
Docker-Image
Zwei manylinux2010 Docker-Images, die auf CentOS 6 basieren, werden für den Bau von binären linux-Wheels bereitgestellt, die zuverlässig in manylinux2010-Wheels konvertiert werden können. [10] Die x86_64- und i686-Images werden mit einer neuen Compiler-Suite ( gcc, g++ und gfortran aus devtoolset-8 ) sowie den neuesten Versionen von Python und pip ausgeliefert.
Kompatibilität mit Kerneln, denen vsyscall fehlt
Ein Docker-Container geht davon aus, dass sein Userland mit dem Kernel seines Hosts kompatibel ist. Leider bricht eine zunehmend verbreitete Kernel-Konfiguration diese Annahme für x86_64 CentOS 6 Docker-Images.
Versionen 2.14 und früher von glibc erfordern, dass der Kernel eine archaische Systemaufruf-Optimierung namens vsyscall auf x86_64 bereitstellt. [11] Zur Effektivierung der Optimierung mappt der Kernel eine schreibgeschützte Seite mit häufig aufgerufenen Systemaufrufen – insbesondere time(2) – in jeden Prozess an einer festen Speicherstelle. glibc ruft diese Systemaufrufe dann auf, indem es einen Funktionszeiger auf den entsprechenden Offset in die vsyscall-Seite dereferenziert und diese aufruft. Dies vermeidet den Overhead, der mit dem Aufruf des Kernels verbunden ist und normale Systemaufrufe beeinflusst. vsyscall ist seit langem zugunsten eines äquivalenten Mechanismus namens vDSO oder „virtual dynamic shared object“ veraltet, bei dem der Kernel stattdessen ein verschiebbares virtuelles Shared Object mit den optimierten Systemaufrufen in jeden Prozess einblendet. [12]
Die vsyscall-Seite hat schwerwiegende Sicherheitsimplikationen, da sie nicht an der Adressraum-Randomisierung (ASLR) teilnimmt. Ihre vorhersagbare Position und ihr Inhalt machen sie zu einer nützlichen Quelle für Gadgets, die in Return-Oriented-Programming-Angriffen verwendet werden. [13] Gleichzeitig bricht ihre Eliminierung die x86_64-ABI, da glibc-Versionen, die von vsyscall abhängen, bei dem Versuch, einen Systemaufrufzeiger auf eine nicht existierende Seite zu dereferenzieren, mit Segmentierungsfehlern zu kämpfen haben. Als Kompromiss implementierte Linux 3.1 ein „emuliertes“ vsyscall, das den ausführbaren Code und damit das Material für ROP-Gadgets reduzierte, das in den Prozess geladen wurde. [14] vsyscall=emulated war jahrelang die Standardkonfiguration in den Kerneln der meisten Distributionen.
Leider exponiert die vsyscall-Emulation immer noch vorhersagbaren Code an einer zuverlässigen Speicherstelle und ist weiterhin für Return-Oriented-Programming nützlich. [15] Da die meisten Distributionen inzwischen auf glibc-Versionen aktualisiert haben, die nicht von vsyscall abhängen, liefern sie zunehmend Kernel aus, die vsyscall gar nicht mehr unterstützen. [16]
CentOS 5.11 und 6 enthalten beide Versionen von glibc, die von der vsyscall-Seite abhängen (2.5 bzw. 2.12.2), sodass Container, die darauf basieren, nicht unter Kerneln ausgeführt werden können, die mit vielen kommenden Distribution-Releases bereitgestellt werden. [17] Wenn Travis CI beispielsweise Jobs unter einem Kernel ausführt, der die vsyscall-Schnittstelle nicht bereitstellt, können Python-Packer unsere Docker-Images dort nicht zum Erstellen von manylinux-Wheels verwenden. [18]
Wir haben einen Patch aus dem glibc Git-Repository abgeleitet, der die Entfernung aller Abhängigkeiten von vsyscall zurückportiert auf die Version von glibc, die in unserem manylinux2010-Image enthalten ist. [19] Das erneute Kompilieren von glibc und damit das Erstellen des manylinux2010-Images selbst erfordert weiterhin einen Host-Kernel, der den vsyscall-Mechanismus bereitstellt, aber das resultierende Image kann sowohl auf Hosts ausgeführt werden, die ihn bereitstellen, als auch auf solchen, die ihn nicht bereitstellen. Da die vsyscall-Schnittstelle eine Optimierung ist, die nur auf laufende Prozesse angewendet wird, sollten die mit diesem modifizierten Image gebauten manylinux2010-Wheels identisch mit denen sein, die auf einem unveränderten CentOS 6-System gebaut wurden. Außerdem betrifft das vsyscall-Problem nur x86_64; es ist kein Teil der i686-ABI.
Auditwheel
Das Werkzeug auditwheel wurde ebenfalls aktualisiert, um manylinux2010-Wheels zu erstellen. [20] Sein Verhalten und Zweck sind ansonsten unverändert gegenüber PEP 513.
Plattformerkennung für Installer
Plattformen können ein boolesches Attribut manylinux2010_compatible auf dem in PEP 513 beschriebenen Modul _manylinux definieren. Eine Plattform gilt als inkompatibel mit manylinux2010, wenn das Attribut False ist.
Wenn das Modul _manylinux nicht gefunden wird oder das Attribut manylinux2010_compatible nicht hat, können Werkzeuge stattdessen auf die Überprüfung von glibc zurückgreifen. Wenn die Plattform glibc 2.12 oder neuer hat, wird sie als kompatibel angenommen, es sei denn, das Modul _manylinux gibt etwas anderes an.
Speziell ist der von uns vorgeschlagene Algorithmus
def is_manylinux2010_compatible():
# Only Linux, and only x86-64 / i686
from distutils.util import get_platform
if get_platform() not in ["linux-x86_64", "linux-i686"]:
return False
# Check for presence of _manylinux module
try:
import _manylinux
return bool(_manylinux.manylinux2010_compatible)
except (ImportError, AttributeError):
# Fall through to heuristic check below
pass
# Check glibc version. CentOS 6 uses glibc 2.12.
# PEP 513 contains an implementation of this function.
return have_compatible_glibc(2, 12)
Abwärtskompatibilität mit manylinux1 Wheels
Wie in PEP 513 erläutert, stellen die angegebenen Symbolversionen für die manylinux1-gewhitelisteten Bibliotheken eine *Obergrenze* dar. Dasselbe gilt für die in dieser PEP für manylinux2010 definierten Symbolversionen. Infolgedessen werden manylinux1-Wheels als manylinux2010-Wheels betrachtet. Ein pip, das den manylinux2010-Plattform-Tag erkennt, wird daher manylinux1-Wheels für manylinux2010-Plattformen installieren – auch wenn explizit gesetzt –, wenn keine manylinux2010-Wheels verfügbar sind. [21]
PyPI-Unterstützung
PyPI sollte das Hochladen von Wheels mit dem manylinux2010-Plattform-Tag zulassen, so wie es manylinux1 zulässt. Es sollte nicht versuchen, die Kompatibilität von manylinux2010-Wheels zu überprüfen.
Zusammenfassung der Änderungen an PEP 571
Die folgenden Änderungen wurden an dieser PEP vorgenommen, basierend auf Feedback, das nach ihrer Genehmigung eingegangen ist
- Die maximale Symbolversion von
libgcc_swurde vonGCC_4.3.0aufGCC_4.5.0aktualisiert, um das 32-Bit-CentOS 6 zu berücksichtigen. Dies beeinträchtigt x86_64 nicht, dalibgcc_sfür x86_64 kein zusätzliches Symbol vonGCC_4.3.0bisGCC_4.5.0hat.
Referenzen
Urheberrecht
Dieses Dokument wurde in den öffentlichen Bereich gestellt.
Quelle: https://github.com/python/peps/blob/main/peps/pep-0571.rst
Zuletzt geändert: 2025-02-01 08:55:40 GMT