diff --git a/python-3.13.yaml b/python-3.13.yaml new file mode 100644 index 00000000000..be8ade5e4c1 --- /dev/null +++ b/python-3.13.yaml @@ -0,0 +1,260 @@ +package: + name: python-3.13 + version: 3.13.0_rc2 + epoch: 0 + description: "the Python programming language" + copyright: + - license: PSF-2.0 + resources: + cpu: 8 + memory: 8Gi + dependencies: + provides: + - python3=0 + - python-3=0 + runtime: + - ${{package.name}}-base=${{package.full-version}} + +environment: + contents: + packages: + - build-base + - busybox + - bzip2-dev + - ca-certificates-bundle + - expat-dev + - gdbm-dev + - libffi-dev + - linux-headers + - mpdecimal-dev + - ncurses-dev + - openssf-compiler-options + - openssl-dev + - readline-dev + - sqlite-dev + - xz-dev + - zlib-dev + +# creates helpfull python3.M and 3.M variables +var-transforms: + - from: ${{package.name}} + match: '-' + replace: '' + to: python + - from: ${{package.version}} + match: (\d).(\d+).(\d+).* + replace: '$1.$2' + to: pyversion + - from: ${{package.version}} + match: '_' + replace: '' + to: tagname + - from: ${{package.version}} + match: (\d).(\d+).(\d+).* + replace: '$1.$2.$3' + to: versionMajMinMic + +pipeline: + - uses: git-checkout + with: + expected-commit: ec610069637d56101896803a70d418a89afe0b4b + repository: https://github.com/python/cpython.git + tag: v${{vars.tagname}} + + - name: Force use of system libraries + runs: | + rm -rf Modules/expat \ + Modules/_ctypes/darwin* \ + Modules/_ctypes/libffi* + + - uses: patch + with: + patches: gh-118224.patch + + - name: Configure + runs: | + ./configure \ + --host=${{host.triplet.gnu}} \ + --build=${{host.triplet.gnu}} \ + --target=${{host.triplet.gnu}} \ + --prefix=/usr \ + --enable-ipv6 \ + --enable-loadable-sqlite-extensions \ + --enable-optimizations \ + --enable-shared \ + --without-lto \ + --with-computed-gotos \ + --with-dbmliborder=gdbm:ndbm \ + --with-system-expat \ + --with-system-ffi \ + --with-system-libmpdec \ + --without-ensurepip \ + --with-builtin-hashlib-hashes=blake2 \ + --with-lto \ + --with-wheel-pkg-dir=/usr/share/python-wheels + + - uses: autoconf/make + + - uses: autoconf/make-install + + - runs: | + find ${{targets.destdir}}/usr/lib -type f -name 'libpython*.a' -exec rm -rf '{}' + + find ${{targets.destdir}}/usr/lib -type d -name 'test' -exec rm -rf '{}' + + find ${{targets.destdir}}/usr/lib -type d -name 'tests' -exec rm -rf '{}' + + find ${{targets.destdir}}/usr/lib -type d -name 'idle_test' -exec rm -rf '{}' + + + cd ${{targets.destdir}}/usr/bin + rm -f idle3* 2to3* + rm ${{targets.destdir}}/usr/lib/libpython3.so + + # add dubious python -> python3 link + ln -s python3 ${{targets.destdir}}/usr/bin/python + + # Drop site-packages README.txt to avoid SCA dep on python3~3.M + cd ${{targets.destdir}}/usr/lib/${{vars.python}} + rm site-packages/README.txt + rmdir site-packages + + - runs: | + rm -R ${{targets.destdir}}/usr/lib/${{vars.python}}/ensurepip/_bundled/ + + - runs: | + find ${{targets.destdir}}/usr/lib -type f -name '*.pyc' -exec rm -rf '{}' + + find ${{targets.destdir}}/usr/lib -type f -name '*.pyo' -exec rm -rf '{}' + + + export LD_LIBRARY_PATH="${{targets.destdir}}/usr/lib${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}" + ${{targets.destdir}}/usr/bin/${{vars.python}} -m compileall --invalidation-mode=unchecked-hash \ + -r100 ${{targets.destdir}}/usr/lib/ + + - uses: strip + +subpackages: + - name: "${{package.name}}-base" + description: "${{package.name}} without /usr/bin/python3" + dependencies: + runtime: + - py3-pip-wheel + pipeline: + - runs: | + mkdir -p ${{targets.subpkgdir}}/usr/bin ${{targets.subpkgdir}}/usr/lib + mv ${{targets.destdir}}/usr/bin/${{vars.python}} \ + ${{targets.destdir}}/usr/bin/pydoc${{vars.pyversion}} \ + ${{targets.subpkgdir}}/usr/bin + mv -v ${{targets.destdir}}/usr/lib/${{vars.python}} \ + ${{targets.subpkgdir}}/usr/lib + mv -v ${{targets.destdir}}/usr/lib/libpython${{vars.pyversion}}.so.* \ + ${{targets.subpkgdir}}/usr/lib + + # pyconfig.h is needed at runtime... ugh. + d=usr/include/${{vars.python}} + mkdir -p "${{targets.subpkgdir}}"/$d + mv "${{targets.destdir}}"/$d/pyconfig.h "${{targets.subpkgdir}}"/$d/ + + # move usr/lib/python3.X/config-3.X-x86_64-linux-gnu + # back into main package so the -base-dev can take it below. + d="usr/lib/${{vars.python}}" + mkdir -p "${{targets.destdir}}/$d" + mv -v "${{targets.subpkgdir}}/$d"/config-${{vars.pyversion}}* \ + "${{targets.destdir}}/$d" + test: + pipeline: + - runs: | + ${{vars.python}} version-check.py ${{vars.versionMajMinMic}} + - name: Verify venv installs expected packages + runs: | + set +x + d=$(mktemp -d) + echo "$ ${{vars.python}} -m venv $d" + ${{vars.python}} -m venv "$d" + echo "$ $d/bin/pip list" + $d/bin/pip list | tee "$d/list.txt" + wd=/usr/share/python-wheels + for pkg in pip ; do + set -- "$wd"/$pkg-*.whl + [ $# -eq 1 ] || { + echo "ERROR: found $# wheels in $wd matching $pkg-*.whl"; + exit 1; + } + [ -f "$1" ] || { + echo "ERROR: $wd/$pkg-*.whl ('$1') was not a file" + exit 1 + } + # name is like pip-24.2-py3-none-any.whl. second token is version. + wheel=${1} + tmp=${wheel##*/} + tmp=${tmp#*-} + ver=${tmp%%-*} + if ! grep -q "$pkg[ ]\+${ver}$" "$d/list.txt"; then + echo "FAIL: did not find '$pkg==$ver' in venv" + echo "pip list had:" + sed 's,^,>,' "$d/list.txt" + exit 1 + fi + echo "PASS: venv installed '$pkg==$ver'" + done + + rm -Rf "$d" + + - name: "${{package.name}}-doc" + description: "python3 documentation" + pipeline: + - uses: split/manpages + + - name: "${{package.name}}-dev" + description: "python3 development headers" + dependencies: + provides: + - python3-dev=0 + - python-3-dev=0 + runtime: + - ${{package.name}}=${{package.full-version}} + - ${{package.name}}-base-dev=${{package.full-version}} + pipeline: + - runs: | + mkdir -p ${{targets.subpkgdir}}/usr/bin + mv -v ${{targets.destdir}}/usr/bin/python3-config ${{targets.subpkgdir}}/usr/bin + + d="usr/lib/pkgconfig" + mkdir -p "${{targets.subpkgdir}}/$d" + mv -v \ + "${{targets.destdir}}"/$d/python3-embed.pc \ + "${{targets.destdir}}"/$d/python3.pc \ + "${{targets.subpkgdir}}/$d/" + + - name: "${{package.name}}-base-dev" + description: "python3 development headers" + dependencies: + runtime: + - ${{package.name}}-base=${{package.full-version}} + pipeline: + - runs: | + # usr/lib/python3.X/config-3.X-x86_64-linux-gnu + # split/dev will only move 2 files from it, but we want all of it. + d="usr/lib/${{vars.python}}" + mkdir -p "${{targets.subpkgdir}}/$d" + mv -v "${{targets.destdir}}"/$d/config-${{vars.pyversion}}* \ + "${{targets.subpkgdir}}"/$d + - uses: split/dev + +test: + pipeline: + - runs: | + # main package should provide 'python' and 'python3'. + python version-check.py ${{vars.versionMajMinMic}} + python3 version-check.py ${{vars.versionMajMinMic}} + - name: Verify working python3 -m venv + runs: | + d=$(mktemp -d) + python3 -m venv "$d" + $d/bin/pip list + $d/bin/pip check + rm -Rf "$d" + +update: + enabled: true + shared: true + github: + identifier: python/cpython + strip-prefix: v + tag-filter: v3.12 + use-tag: true diff --git a/python-3.13/gh-118224.patch b/python-3.13/gh-118224.patch new file mode 100644 index 00000000000..083abb18dab --- /dev/null +++ b/python-3.13/gh-118224.patch @@ -0,0 +1,82 @@ +Upstream: https://github.com/python/cpython/issues/118224 + +From 49f920e41aef131f7f11657a65a4a986839ea193 Mon Sep 17 00:00:00 2001 +From: Dimitri John Ledkov +Date: Wed, 24 Apr 2024 14:47:10 +0100 +Subject: [PATCH 1/2] [3.12] gh-118224: Load default OpenSSL provider for + nonsecurity algorithms + +When OpenSSL is configured to only load "base+fips" providers into the +Null library context, md5 might not be available at all. In such cases +currently CPython fallsback to internal hashlib implementation is +there is one - as there might not be if one compiles python with +--with-builtin-hashlib-hashes=blake2. With this change "default" +provider is attempted to be loaded to access nonsecurity hashes. +--- + Modules/_hashopenssl.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c +index 2998820953bda9..9b28c5174bfe3e 100644 +--- a/Modules/_hashopenssl.c ++++ b/Modules/_hashopenssl.c +@@ -56,6 +56,7 @@ + #endif + + #if OPENSSL_VERSION_NUMBER >= 0x30000000L ++#include + #define PY_EVP_MD EVP_MD + #define PY_EVP_MD_fetch(algorithm, properties) EVP_MD_fetch(NULL, algorithm, properties) + #define PY_EVP_MD_up_ref(md) EVP_MD_up_ref(md) +@@ -265,6 +266,17 @@ typedef struct { + _Py_hashtable_t *hashtable; + } _hashlibstate; + ++static void try_load_default_provider(void) { ++#if OPENSSL_VERSION_NUMBER >= 0x30000000L ++ /* Load the default config file, and expected providers */ ++ OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL); ++ if (!OSSL_PROVIDER_available(NULL, "default")) { ++ /* System is configured without the default provider */ ++ OSSL_PROVIDER_load(NULL, "default"); ++ } ++#endif ++} ++ + static inline _hashlibstate* + get_hashlib_state(PyObject *module) + { +@@ -386,6 +398,7 @@ py_digest_by_name(PyObject *module, const char *name, enum Py_hash_type py_ht) + break; + case Py_ht_evp_nosecurity: + if (entry->evp_nosecurity == NULL) { ++ try_load_default_provider(); + entry->evp_nosecurity = PY_EVP_MD_fetch(entry->ossl_name, "-fips"); + } + digest = entry->evp_nosecurity; +@@ -403,6 +416,7 @@ py_digest_by_name(PyObject *module, const char *name, enum Py_hash_type py_ht) + digest = PY_EVP_MD_fetch(name, NULL); + break; + case Py_ht_evp_nosecurity: ++ try_load_default_provider(); + digest = PY_EVP_MD_fetch(name, "-fips"); + break; + } + +From d5e209887d7fa05e46afc1d17dc362cccb0bd53b Mon Sep 17 00:00:00 2001 +From: Dimitri John Ledkov +Date: Wed, 24 Apr 2024 23:28:53 +0100 +Subject: [PATCH 2/2] Add blurb + +--- + .../next/Build/2024-04-24-16-58-45.gh-issue-118224.wnjFHn.rst | 1 + + 1 file changed, 1 insertion(+) + create mode 100644 Misc/NEWS.d/next/Build/2024-04-24-16-58-45.gh-issue-118224.wnjFHn.rst + +diff --git a/Misc/NEWS.d/next/Build/2024-04-24-16-58-45.gh-issue-118224.wnjFHn.rst b/Misc/NEWS.d/next/Build/2024-04-24-16-58-45.gh-issue-118224.wnjFHn.rst +new file mode 100644 +index 00000000000000..c63b71ecbafc58 +--- /dev/null ++++ b/Misc/NEWS.d/next/Build/2024-04-24-16-58-45.gh-issue-118224.wnjFHn.rst +@@ -0,0 +1 @@ ++Hashlib now supports using default OpenSSL provider instead of builtin fallback for nonsecurity hashes on hosts otherwise only using base and fips providers. This makes build configuration ``--with-builtin-hashlib-hashes=blake2`` fully supported on OpenSSL FIPS hosts. diff --git a/python-3.13/version-check.py b/python-3.13/version-check.py new file mode 100644 index 00000000000..9a2899bb897 --- /dev/null +++ b/python-3.13/version-check.py @@ -0,0 +1,12 @@ +import sys + +info = sys.version_info +found = "%s.%s.%s" % (info.major, info.minor, info.micro) + +if len(sys.argv) > 1: + expected = sys.argv[1] + if found != expected: + print("ERROR: expected version '%s' found '%s'" % (expected, found)) + sys.exit(1) + +print("python version: " + found)