erplibre/script/install/install_fedora_dependency.sh
Mathieu Benoit a579cc9cf3 [FIX] install: the EL9, EL10 and Fedora build chain
"dnf install: error: unrecognized arguments" on AlmaLinux 10 and Rocky 10,
on every call: PostgreSQL, build dependencies, pyenv. The tools group got
away with its fallback, which made the trace misleading -- gcc installed,
nothing after it did.

"--skip-unavailable" is a dnf5 option, which the script's own comment
already said while assuming it everywhere. Fedora 41+ ships dnf5, but EL9
and EL10 stay on dnf4, whose equivalent is "--setopt=strict=0". We now ask
dnf what it understands instead of inferring it from the distribution.

Three neighbouring fixes: the "c-development" group does not exist on EL,
where it is called "development"; CRB is enabled through /usr/bin/crb; and
g++ plus the missing headers are installed explicitly. Rust is added only
where wheels are absent, and qpdf is built when the distribution ships one
older than pikepdf demands.

--- FR ---

« dnf install: error: unrecognized arguments » sur AlmaLinux 10 et
Rocky 10, à chaque appel : PostgreSQL, dépendances de compilation, pyenv.
Le groupe d'outils s'en tirait par son repli, ce qui rendait la trace
trompeuse — gcc installé, rien après lui.

« --skip-unavailable » est une option de dnf5, ce que le commentaire du
script disait déjà tout en la supposant partout. Fedora 41+ livre dnf5,
mais EL9 et EL10 restent sur dnf4, dont l'équivalent est
« --setopt=strict=0 ». On demande maintenant à dnf ce qu'il comprend
plutôt que de le déduire de la distribution.

Trois correctifs voisins : le groupe « c-development » n'existe pas sur
EL, où il s'appelle « development » ; CRB s'active par /usr/bin/crb ; et
g++ ainsi que les en-têtes manquants sont posés explicitement. Rust n'est
ajouté que là où les roues manquent, et qpdf est compilé quand la
distribution en livre un plus ancien que ce qu'exige pikepdf.

Assisted-by: Claude Opus 5
2026-08-16 23:33:49 -04:00

256 lines
12 KiB
Bash
Executable file

#!/usr/bin/env bash
# © 2021-2026 TechnoLibre (http://www.technolibre.ca)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
#
# Dépendances système ERPLibre pour la famille dnf : Fedora, mais aussi
# AlmaLinux, Rocky et RHEL, qu'install_dev.sh aiguille ici sur ID_LIKE=rhel.
# Équivalent de install_debian_dependency.sh.
#
# Attention : Fedora 41+ livre dnf5, EL9 et EL10 encore dnf4. Les deux ne
# comprennent pas les mêmes options — voir DNF_SKIP plus bas.
. ./env_var.sh
. ./script/install/lib_qpdf.sh
EL_USER=${USER}
# « Sauter un paquet introuvable au lieu d'échouer sur tout le lot » ne
# s'écrit PAS pareil selon la version de dnf : « --skip-unavailable » est une
# option de dnf5 (Fedora 41+), et dnf4 — encore livré par EL9 et EL10, donc
# par AlmaLinux et Rocky — la refuse net : « dnf install: error: unrecognized
# arguments ». Son équivalent y est « --setopt=strict=0 ». On demande donc à
# dnf lui-même ce qu'il comprend, plutôt que de deviner d'après la distro.
if dnf install --help 2>&1 | grep -q -- "--skip-unavailable"; then
DNF_SKIP="--skip-unavailable"
else
DNF_SKIP="--setopt=strict=0"
fi
echo "dnf : option de tolerance retenue = ${DNF_SKIP}"
# dnf résilient : rafraîchit le cache (évite « checksum doesn't match » /
# signature après un cache périmé) et saute les paquets introuvables.
DNF="sudo dnf install -y --refresh ${DNF_SKIP}"
#--------------------------------------------------
# Dérivés RHEL : dépôts supplémentaires
#--------------------------------------------------
# AlmaLinux, Rocky, CentOS Stream et RHEL passent par ce script (install_dev.sh
# les aiguille sur ID_LIKE=rhel). Contrairement à Fedora, leur jeu de dépôts
# par défaut est ÉTROIT : la plupart des paquets « -devel » vivent dans CRB
# (CodeReady Builder), et tout ce qui est communautaire dans EPEL. Sans ces
# deux dépôts, la tolérance aux paquets absents les saute EN SILENCE et
# l'échec n'apparaît qu'à la compilation, très loin d'ici.
if [ -r /etc/os-release ]; then
# shellcheck disable=SC1091
. /etc/os-release
fi
case "${ID}" in
almalinux | rocky | rhel | centos)
echo -e "\n---- Depots EPEL et CRB (famille RHEL) ----"
sudo dnf install -y epel-release \
|| echo "epel-release indisponible : certains paquets manqueront."
# /usr/bin/crb est l'outil fourni par epel-release, et ce que son propre
# scriptlet recommande d'exécuter — plus fiable que de deviner le nom du
# dépôt, qui vaut « crb » sur EL9/EL10 et « powertools » sur EL8.
sudo /usr/bin/crb enable 2> /dev/null \
|| sudo dnf config-manager --set-enabled crb 2> /dev/null \
|| sudo dnf config-manager --set-enabled powertools 2> /dev/null \
|| sudo dnf config-manager --enable crb 2> /dev/null \
|| echo "CRB/PowerTools non active : certains -devel manqueront."
# Un dépôt fraîchement activé dont les métadonnées ne descendent pas fait
# échouer TOUS les dnf suivants. On le voit ici, avec son nom, plutôt que
# trois sections plus loin sur un paquet sans rapport.
sudo dnf makecache 2> /dev/null \
|| { sudo dnf clean all; sudo dnf makecache; } \
|| echo "Attention : metadonnees de depot incompletes."
;;
esac
#--------------------------------------------------
# Outils de compilation (build Python via pyenv, extensions Python)
#--------------------------------------------------
echo -e "\n---- Outils de developpement ----"
# Les GROUPES ne sont pas les mêmes d'une famille à l'autre : Fedora a
# « c-development », EL ne connaît que « development » — vérifié dans le
# comps.xml d'AlmaLinux 10, qui n'a même pas « development-tools ».
#
# Pire, la tolérance aux paquets absents les rend INOFFENSIFS : un
# « dnf group install » de deux groupes inconnus REND ZÉRO sans rien poser,
# donc le « || » de repli ne se déclenchait jamais. gcc arrivait par la
# section pyenv plus bas, gcc-c++ par personne, et numpy s'arrêtait sur
# « Unknown compiler(s): [['c++'], ['g++'], …] ».
#
# On installe donc les compilateurs EXPLICITEMENT, sans dépendre d'un groupe.
# Le groupe reste ensuite, en complément et en best-effort.
${DNF} gcc gcc-c++ make automake patch
retVal=$?
if [[ $retVal -ne 0 ]]; then
echo "dnf install compilers error."
exit 1
fi
sudo dnf group install -y ${DNF_SKIP} development c-development \
> /dev/null 2>&1 || true
#--------------------------------------------------
# Mainframe s390x
#--------------------------------------------------
# Sur s390x, AUCUNE roue PyPI n'existe : numpy, pillow, lxml, pikepdf,
# psycopg2, cryptography… tout se compile contre les bibliothèques de la
# distribution. Ces en-têtes ne servent à rien sur amd64, où pip pose des
# roues, mais leur absence ici arrête l'installation très loin de sa cause —
# « The headers or library files could not be found for jpeg » pour pillow.
if [ "$(uname -m)" = "s390x" ]; then
echo -e "\n---- Dependances de compilation s390x ----"
# Best-effort : un nom qui change d'une version à l'autre ne doit pas
# emporter le lot. Ce qui est vraiment indispensable est déjà installé
# au-dessus (compilateurs) ou plus bas (pyenv, PostgreSQL).
# « rust » et « cargo » : plusieurs paquets Python portent une extension
# RUST, pas seulement C — bcrypt et cryptography en tête. Sur amd64 leurs
# roues masquent le besoin ; ici tout compile, et bcrypt s'arrête net sur
# « error: can't find Rust compiler ». Les versions livrées suffisent
# (AlmaLinux 1.92, Fedora plus récent) au Cargo.lock v4 qui exige 1.78.
${DNF} \
rust cargo \
libjpeg-turbo-devel zlib-devel geos-devel proj-devel \
krb5-devel tbb-devel ninja-build clang-devel llvm-devel \
GeographicLib-devel pkgconf-pkg-config cmake
# qpdf : pikepdf en exige 12.2.0, et le paquet de la distribution ne le donne
# que sur Fedora. EL9 livre 10.3 — même pas « qpdf/QPDFJob.hh », d'où trois
# cents lignes de g++ sans un mot sur qpdf ; EL10 livre 11.9.
#
# On ne pose donc « qpdf-devel » QUE s'il atteint le seuil, au lieu de le
# poser puis de le contourner : contrairement à Debian, l'éditeur de liens de
# RHEL cherche /usr/lib64 AVANT /usr/local/lib64. Le -devel trop ancien ferait
# lier pikepdf contre l'ancienne bibliothèque malgré les en-têtes neufs de
# /usr/local/include — une incohérence bien plus difficile à lire qu'un
# en-tête absent. Sans lui, el_qpdf_ensure fournit tout depuis les sources.
qpdf_repo="$(dnf repoquery --qf '%{version}' --latest-limit 1 qpdf-devel \
2> /dev/null | tail -1)"
if el_qpdf_ge_min "${qpdf_repo}"; then
${DNF} qpdf-devel
else
echo "qpdf-devel ${qpdf_repo:-absent} sous le seuil de pikepdf : compilation depuis les sources."
fi
el_qpdf_ensure
# Le dire ICI plutôt que de laisser bcrypt le découvrir une heure plus tard.
if ! command -v cargo > /dev/null 2>&1; then
echo "Attention : cargo absent, bcrypt et cryptography ne compileront pas."
fi
# pymupdf charge « libclang.so » par son nom nu, via ctypes. Le paquet le
# livre sous un nom versionné : il ne manque que le lien.
for d in /usr/lib64 /usr/lib; do
if [ -d "${d}" ] && [ ! -e "${d}/libclang.so" ]; then
so="$(ls -1 "${d}"/libclang.so.* 2> /dev/null | sort -V | tail -1)"
if [ -n "${so}" ]; then
sudo ln -s "${so}" "${d}/libclang.so" && sudo ldconfig
echo "libclang.so -> ${so}"
fi
fi
done
fi
#--------------------------------------------------
# PostgreSQL
#--------------------------------------------------
echo -e "\n---- Install PostgreSQL Server ----"
${DNF} postgresql-server postgresql-contrib libpq-devel
retVal=$?
if [[ $retVal -ne 0 ]]; then
echo "dnf install postgresql installation error."
exit 1
fi
# Initialisation du cluster (Fedora ne le fait pas automatiquement).
if [ ! -f /var/lib/pgsql/data/PG_VERSION ]; then
echo -e "\n---- Initialisation du cluster PostgreSQL ----"
# Nettoie un init partiel et FORCE une locale valide : les images cloud
# Fedora n'ont pas de LANG défini -> « initdb: invalid locale settings ».
sudo rm -rf /var/lib/pgsql/data
sudo PGSETUP_INITDB_OPTIONS="--locale=C.UTF-8 --encoding=UTF8" \
postgresql-setup --initdb || true
fi
sudo systemctl enable --now postgresql 2>/dev/null || true
# PostGIS : optionnel (géospatial), ne bloque pas.
${DNF} postgis || echo "PostGIS non installé (optionnel)."
echo -e "\n---- Creating the ERPLibre PostgreSQL User ----"
sudo su - postgres -c "createuser -s ${EL_USER}" 2>/dev/null || true
#--------------------------------------------------
# Dépendances de build (extensions Python, Odoo)
#--------------------------------------------------
echo -e "\n--- Installing fedora dependency --"
# git-daemon : sur Fedora la sous-commande « git daemon » N'EST PAS dans le
# paquet « git » de base (contrairement à Debian/Ubuntu/Arch). ERPLibre sert
# son manifeste via un « git daemon » local (git://127.0.0.1:9418/) pendant
# « repo sync » -> sans ce paquet : « git: 'daemon' is not a git command »
# puis « Connection refused » et l'échec de la synchro du manifeste.
${DNF} \
git git-daemon wget libxslt-devel libzip-devel openldap-devel \
cyrus-sasl-devel \
libffi-devel bzip2-devel parallel swig cmake portaudio-devel \
cups-devel xmlsec1 xmlsec1-openssl mariadb-connector-c-devel freetds-devel
retVal=$?
if [[ $retVal -ne 0 ]]; then
echo "dnf fedora tool installation error."
exit 1
fi
# Dépendances de build pour pyenv (compilation de CPython) — CRITIQUE.
echo -e "\n---- Dépendances pyenv (compilation Python) ----"
${DNF} \
make gcc zlib-devel bzip2 bzip2-devel readline-devel sqlite sqlite-devel \
openssl-devel tk-devel libffi-devel xz-devel patch findutils
retVal=$?
if [[ $retVal -ne 0 ]]; then
echo "dnf pyenv dependencies installation error."
exit 1
fi
# Dépendances selenium / bindings.
${DNF} \
cairo-devel python3-devel pkgconf-pkg-config gobject-introspection-devel \
libXt-devel || echo "Dépendances selenium partielles (optionnel)."
#--------------------------------------------------
# Node.js + npm (rtlcss, less)
#--------------------------------------------------
echo -e "\n---- Installing nodeJS NPM and rtlcss ----"
${DNF} nodejs npm
retVal=$?
if [[ $retVal -ne 0 ]]; then
echo "dnf nodejs installation error."
exit 1
fi
sudo npm install -g rtlcss less || echo "npm rtlcss/less: erreur (optionnel)."
echo -e "\n---- Test tool ----"
npm install || echo "npm install (prettier/plugin-xml): erreur (optionnel)."
sudo ln -fs /usr/local/bin/lessc /usr/bin/lessc 2>/dev/null || true
#--------------------------------------------------
# nginx (optionnel)
#--------------------------------------------------
if [ "${EL_INSTALL_NGINX}" = "True" ]; then
echo -e "\n---- Installing nginx ----"
${DNF} nginx || echo "nginx: erreur (optionnel)."
fi
#--------------------------------------------------
# wkhtmltopdf (optionnel) — paquet RPM officiel wkhtmltopdf
#--------------------------------------------------
if [ "${EL_INSTALL_WKHTMLTOPDF}" = "True" ]; then
if ! command -v wkhtmltopdf >/dev/null 2>&1; then
echo -e "\n---- Installing wkhtml (best-effort) ----"
# wkhtmltopdf ne publie plus de build « fedora-* » ; le RPM AlmaLinux 9
# (EL9) est compatible Fedora (testé sur F42 : dnf résout les deps).
# Repli AlmaLinux 8 au besoin.
_base="https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-3"
sudo dnf install -y "${_base}/wkhtmltox-0.12.6.1-3.almalinux9.x86_64.rpm" \
|| sudo dnf install -y "${_base}/wkhtmltox-0.12.6.1-3.almalinux8.x86_64.rpm" \
|| echo "wkhtmltopdf non installé (optionnel)."
else
echo -e "\n---- Already installed wkhtml ----"
fi
fi
echo -e "\n---- Fedora dependency installation done ----"