[REM] install: drop Ubuntu 20.04 and 22.04

Two blockers on 20.04, neither worth carrying. "TypeError: unsupported
operand type(s) for |" fired before the install even started:
update_env_version.py imports erplibre_state as the very first thing
"make install_os" does, hence before pyenv, on the system Python 3.8,
where a "str | None" annotation is evaluated at import. And cryptography
now demands OpenSSL 3, while focal ships 1.1.1.

Annotations are therefore deferred, a contract the bootstrap file already
stated in a comment and now holds across script/version and
script/install. But the releases themselves go: pikepdf requires
qpdf >= 12.2, compiled in C++20, when focal ships GCC 9.

--- FR ---

Deux blocages sur 20.04, aucun ne méritant d'être porté. « TypeError:
unsupported operand type(s) for | » se déclenchait avant même le début de
l'installation : update_env_version.py importe erplibre_state en tout
premier lieu de « make install_os », donc avant pyenv, sur le Python 3.8
du système, où une annotation « str | None » est évaluée à l'import. Et
cryptography exige désormais OpenSSL 3, quand focal livre 1.1.1.

Les annotations sont donc différées, contrat que le fichier d'amorçage
énonçait déjà en commentaire et qui tient maintenant sur script/version et
script/install. Mais les versions elles-mêmes partent : pikepdf réclame
qpdf >= 12.2, compilé en C++20, quand focal livre GCC 9.

Assisted-by: Claude Opus 5
This commit is contained in:
Mathieu Benoit 2026-08-11 08:03:32 -04:00
parent b6de9b5506
commit 42391575d6
8 changed files with 132 additions and 1 deletions

View file

@ -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.

View file

@ -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

View file

@ -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
<!-- [fr] -->
@ -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
<!-- [common] -->

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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,

View file

@ -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