diff --git a/script/install/install_debian_dependency.sh b/script/install/install_debian_dependency.sh index e0022ea..c7e6a6f 100755 --- a/script/install/install_debian_dependency.sh +++ b/script/install/install_debian_dependency.sh @@ -58,6 +58,25 @@ fi #-------------------------------------------------- if [ "$(uname -m)" = "s390x" ]; then echo "Arch s390x detected" + # Sur s390x, aucune roue PyPI : tout se compile contre les bibliothèques de + # la distribution. Deux versions n'en ont pas d'assez récentes. + # + # 20.04 : pikepdf réclame qpdf >= 12.2, dont la compilation exige C++20. + # focal livre GCC 9 et ne publie PAS g++-10 pour s390x — vérifié. + # La compilation s'arrête sur « fatal error: concepts: No such file + # or directory », sans contournement possible. + # 22.04 : même mur qpdf, franchissable en théorie, abandonné avec la 20.04 + # plutôt que de maintenir un chemin de plus. + # + # On refuse ICI, avant une heure de compilation émulée pour rien. + case "${UBUNTU_VERSION}" in + 20.04 | 22.04) + echo "Ubuntu ${UBUNTU_VERSION} n'est plus supporte sur s390x :" + echo " sa chaine d'outils est trop ancienne pour ERPLibre." + echo " Utilisez Ubuntu 24.04 ou plus recent." + exit 1 + ;; + esac # Sur une VM fraîche, l'index apt peut être vide : « apt install » échouerait # alors sur TOUT le lot, et l'absence d'un seul paquet ne se voit que bien # plus loin, sous la forme d'une commande introuvable. diff --git a/script/install/install_locally.sh b/script/install/install_locally.sh index 350b86a..585fe26 100755 --- a/script/install/install_locally.sh +++ b/script/install/install_locally.sh @@ -81,10 +81,39 @@ if [[ "${EL_PHASE}" != "setup" ]]; then exit 1 fi + # s390x UNIQUEMENT — la borne ci-dessous ne doit toucher aucune autre + # architecture, et le test d'architecture vient donc en premier. + # + # Poetry tire keyring, donc SecretStorage, donc cryptography, dont la + # DERNIÈRE version : rien ne la borne à cette étape. Partout ailleurs c'est + # sans conséquence, pip y pose une roue manylinux qui embarque son propre + # OpenSSL en statique — vérifié, la 50.0.0 en publie pour x86_64, aarch64, + # ppc64le et armv7l. s390x est la SEULE sans roue : elle compile, contre + # l'OpenSSL du système. + # + # Or cryptography 47 a retiré le support d'OpenSSL 1.1.1 — vérifié version + # par version, les gardes « CRYPTOGRAPHY_OPENSSL_300_OR_GREATER » de + # fips.rs disparaissent entre la 46 et la 47 — et Ubuntu 20.04 livre + # 1.1.1f. D'où « EVP_default_properties_is_fips_enabled not found in ffi ». + # Sur s390x en 22.04 et au-delà, OpenSSL est en 3.x : aucune borne. + PIP_CONSTRAINT_CRYPTO="" + if [[ "$(uname -m)" == "s390x" ]]; then + OPENSSL_VER="$(pkg-config --modversion openssl 2>/dev/null \ + || openssl version 2>/dev/null | awk '{print $2}')" + case "${OPENSSL_VER}" in + 3.* | 4.*) ;; + "") echo "s390x : version d'OpenSSL indeterminee, aucune borne." ;; + *) + echo "s390x, OpenSSL ${OPENSSL_VER} < 3 : cryptography borne a <47 pour poetry." + PIP_CONSTRAINT_CRYPTO="cryptography<47" + ;; + esac + fi + # Delete artifacts created by pip, cause error in next "poetry install" if [[ ! -f "${POETRY_ODOO_PATH}" ]]; then echo -e "Install Poetry ${POETRY_ODOO_PATH}" - pip install poetry==${EL_POETRY_VERSION} + pip install ${PIP_CONSTRAINT_CRYPTO} poetry==${EL_POETRY_VERSION} poetry --version # Fix broken poetry by installing ignored dependence # poetry lock --no-update diff --git a/script/qemu/README.base.md b/script/qemu/README.base.md index 116a496..33daefb 100644 --- a/script/qemu/README.base.md +++ b/script/qemu/README.base.md @@ -177,6 +177,13 @@ Supported Ubuntu versions: `20.04`, `22.04`, `24.04` (default), `24.10`, `25.04`, `25.10`. Provide an explicit image path as a positional argument to override the automatic download location. +On **s390x**, `20.04` and `22.04` are **not supported**: no PyPI wheel exists +for that architecture, so everything is built against the distribution's +libraries, and pikepdf needs qpdf 12.2, whose build requires C++20. Focal +ships GCC 9 and publishes no `g++-10` for s390x — there is no way around it. +Use `24.04` or later. Both are still supported on amd64 and arm64, where pip +installs prebuilt wheels. + ## After deployment @@ -184,6 +191,14 @@ Versions Ubuntu supportées : `20.04`, `22.04`, `24.04` (défaut), `24.10`, `25.04`, `25.10`. Fournissez un chemin d'image en argument positionnel pour surcharger l'emplacement de téléchargement automatique. +Sur **s390x**, les `20.04` et `22.04` ne sont **pas supportées** : aucune roue +PyPI n'existe pour cette architecture, tout se compile donc contre les +bibliothèques de la distribution, et pikepdf réclame qpdf 12.2, dont la +compilation exige C++20. Focal livre GCC 9 et ne publie pas de `g++-10` pour +s390x — il n'y a pas de contournement. Utilisez la `24.04` ou plus récente. +Les deux restent supportées sur amd64 et arm64, où pip pose des roues +précompilées. + ## Après le déploiement diff --git a/script/qemu/README.fr.md b/script/qemu/README.fr.md index afae765..21dfe7f 100644 --- a/script/qemu/README.fr.md +++ b/script/qemu/README.fr.md @@ -96,6 +96,14 @@ Versions Ubuntu supportées : `20.04`, `22.04`, `24.04` (défaut), `24.10`, `25.04`, `25.10`. Fournissez un chemin d'image en argument positionnel pour surcharger l'emplacement de téléchargement automatique. +Sur **s390x**, les `20.04` et `22.04` ne sont **pas supportées** : aucune roue +PyPI n'existe pour cette architecture, tout se compile donc contre les +bibliothèques de la distribution, et pikepdf réclame qpdf 12.2, dont la +compilation exige C++20. Focal livre GCC 9 et ne publie pas de `g++-10` pour +s390x — il n'y a pas de contournement. Utilisez la `24.04` ou plus récente. +Les deux restent supportées sur amd64 et arm64, où pip pose des roues +précompilées. + ## Après le déploiement ```bash diff --git a/script/qemu/README.md b/script/qemu/README.md index f4d8b02..9335a43 100644 --- a/script/qemu/README.md +++ b/script/qemu/README.md @@ -90,6 +90,13 @@ Supported Ubuntu versions: `20.04`, `22.04`, `24.04` (default), `24.10`, `25.04`, `25.10`. Provide an explicit image path as a positional argument to override the automatic download location. +On **s390x**, `20.04` and `22.04` are **not supported**: no PyPI wheel exists +for that architecture, so everything is built against the distribution's +libraries, and pikepdf needs qpdf 12.2, whose build requires C++20. Focal +ships GCC 9 and publishes no `g++-10` for s390x — there is no way around it. +Use `24.04` or later. Both are still supported on amd64 and arm64, where pip +installs prebuilt wheels. + ## After deployment ```bash diff --git a/script/qemu/deploy_qemu.py b/script/qemu/deploy_qemu.py index f8f570b..f7e0f19 100755 --- a/script/qemu/deploy_qemu.py +++ b/script/qemu/deploy_qemu.py @@ -128,6 +128,31 @@ NON_X86_ARCHES: tuple[str, ...] = ("arm64", "s390x") # aarch64 sur geo.mirror.pkgbuild.com). S390X_DISTROS: tuple[str, ...] = ("ubuntu",) ARM64_DISTROS: tuple[str, ...] = ("ubuntu", "debian", "fedora") + +# Versions ABANDONNÉES sur une architecture donnée : publier une image cloud ne +# suffit pas, encore faut-il que la chaîne d'outils permette d'installer +# ERPLibre. Sur s390x, aucune roue PyPI n'existe : tout se compile contre les +# bibliothèques de la distribution, et deux versions n'en ont pas d'assez +# récentes. +# +# 20.04 : pikepdf réclame qpdf >= 12.2, dont la compilation exige C++20 — +# or focal livre GCC 9 et NE PUBLIE PAS g++-10 pour s390x. Sans +# issue. S'y ajoutaient Python 3.8, node 10, cargo 0.67 et +# OpenSSL 1.1.1, tous contournés, mais celui-là ne l'est pas. +# 22.04 : même mur qpdf, franchissable en théorie (GCC 11), abandonné avec +# la 20.04 pour ne pas maintenir un chemin de plus. +# +# amd64 et arm64 ne sont PAS concernés : pip y pose des roues précompilées. +UNSUPPORTED_VERSIONS: dict[str, dict[str, tuple[str, ...]]] = { + "s390x": {"ubuntu": ("20.04", "22.04")}, +} + + +def is_supported(distro: str, version: str, arch: str) -> bool: + """Faux si ce triplet est explicitement abandonné.""" + return version not in UNSUPPORTED_VERSIONS.get(arch, {}).get(distro, ()) + + # arch générique -> distros la publiant (pour valider --arch tôt). ARCH_DISTRO_SUPPORT: dict[str, tuple[str, ...]] = { "s390x": S390X_DISTROS, @@ -2084,6 +2109,19 @@ def main() -> None: f"Architecture {args.arch} indisponible pour {args.distro!r} : " f"images cloud publiées seulement pour {', '.join(supported)}." ) + # L'image cloud existe, mais la chaîne d'outils de cette version ne permet + # pas d'installer ERPLibre sur cette architecture. Mieux vaut le dire ici + # qu'après une heure de compilation émulée. + if not is_supported(args.distro, args.version, args.arch): + dropped = UNSUPPORTED_VERSIONS[args.arch][args.distro] + keep = [v for v in versions if v not in dropped] + sys.exit( + f"{args.distro} {args.version} n'est plus supporté sur " + f"{args.arch} : sa chaîne d'outils est trop ancienne pour " + f"ERPLibre (GCC 9 sur 20.04 ne compile pas le qpdf que réclame " + f"pikepdf, et aucun g++ plus récent n'y est publié).\n" + f" Versions supportées sur {args.arch} : {', '.join(keep)}." + ) code, default_osinfo, min_ram, min_disk = versions[args.version] if args.codename: code = args.codename diff --git a/script/todo/todo.py b/script/todo/todo.py index c4e7d7f..5a9b238 100755 --- a/script/todo/todo.py +++ b/script/todo/todo.py @@ -4987,10 +4987,17 @@ class TODO: déployable, aussi bien pour la liste granulaire de la CLI que pour la liste à cocher du formulaire TUI.""" flat = [] + # Le catalogue ne propose que ce qui s'installe. La liste des versions + # abandonnées vit dans deploy_qemu.py, qui refuse aussi de les + # déployer : une seule source, donc pas d'écran offrant un choix que + # la couche du dessous rejettera. + supported = getattr(mod, "is_supported", None) for d in distros: versions_map, default_v = mod.DISTROS[d] for v, (_c, _o, ram, disk) in versions_map.items(): for a in self._qemu_arches_for(d, arch): + if supported and not supported(d, v, a): + continue flat.append( { "distro": d, diff --git a/script/version/erplibre_state.py b/script/version/erplibre_state.py index 790434c..9c5c529 100644 --- a/script/version/erplibre_state.py +++ b/script/version/erplibre_state.py @@ -9,8 +9,16 @@ This file tracks what is installed in the current ERPLibre workspace: - Which Odoo versions are installed, and with which options (extra, etc.) - Whether the mobile project is active - The currently active Odoo version + +`update_env_version.py` imports this module as the FIRST thing `make +install_os` runs, donc avant pyenv : il s'exécute sur le Python DU SYSTÈME, +3.8 sur Ubuntu 20.04. Les annotations doivent rester différées — sans quoi +« str | None » (PEP 604) ou « list[str] » (PEP 585) sont évaluées à +l'import et lèvent un TypeError avant même que l'installation commence. """ +from __future__ import annotations + import json import logging import os