[IMP] install: support Fedora, Debian, Ubuntu and Arch
Adds a Fedora dependency installer, rewrites the Arch one on pacman rather than an AUR helper absent from cloud images, and repairs the Debian path: apt lock timeout, PostGIS best-effort, Ubuntu 26.04, Node 22. --- FR --- Ajoute un installeur de dépendances Fedora, réécrit celui d'Arch sur pacman plutôt qu'un assistant AUR absent des images cloud, et répare le chemin Debian : attente du verrou apt, PostGIS best-effort, Ubuntu 26.04, Node 22. Assisted-by: Claude Opus 4.8 Assisted-by: Claude Opus 5
This commit is contained in:
parent
63534e0473
commit
dd98955192
7 changed files with 410 additions and 84 deletions
|
|
@ -1,68 +1,126 @@
|
|||
#!/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 Arch Linux (pacman). Réécrit pour les
|
||||
# images cloud Arch : l'ancien script utilisait « yay » (helper AUR ABSENT
|
||||
# d'une image cloud et qui refuse de tourner en root) et n'installait jamais
|
||||
# « base-devel » -> pas de compilateur C -> échec de la compilation de Python
|
||||
# par pyenv. On passe tout par pacman (dépôts officiels) ; l'AUR (wkhtmltopdf)
|
||||
# est best-effort et ne bloque pas.
|
||||
|
||||
install_package() {
|
||||
local package_name=$1
|
||||
. ./env_var.sh
|
||||
|
||||
# Check package is already installed
|
||||
if pacman -Qs "$package_name" >/dev/null; then
|
||||
echo "$package_name is already installed."
|
||||
else
|
||||
echo "Installation of package $package_name..."
|
||||
yes | yay -S "$package_name"
|
||||
fi
|
||||
}
|
||||
EL_USER=${USER}
|
||||
|
||||
# Odoo installation
|
||||
install_package postgis
|
||||
install_package postgresql
|
||||
install_package mariadb
|
||||
install_package libev
|
||||
install_package wkhtmltopdf
|
||||
install_package freetds
|
||||
# pacman résilient : --needed saute ce qui est déjà là, --noconfirm en non
|
||||
# interactif.
|
||||
PAC="sudo pacman -S --needed --noconfirm"
|
||||
# Mise à jour COMPLÈTE obligatoire : Arch est en rolling release et NE SUPPORTE
|
||||
# PAS les mises à jour partielles. Sur une image cloud dont la glibc est
|
||||
# ancienne, un « pacman -S <paquet récent> » lie le binaire à une glibc plus
|
||||
# récente que celle installée -> « /usr/bin/postgres: GLIBC_2.44 not found ».
|
||||
# « -Syu » met à jour glibc (et tout le système) pour rester cohérent.
|
||||
sudo pacman -Syu --noconfirm || true
|
||||
|
||||
echo "Need password to create symbolic link, create postgres user and install npm :"
|
||||
sudo ln -fs /usr/lib/libldap.so /usr/lib/libldap_r.so
|
||||
#--------------------------------------------------
|
||||
# Outils de compilation — CRITIQUE (build Python via pyenv, extensions Python)
|
||||
# base-devel fournit gcc, make, patch, pkgconf, fakeroot, etc.
|
||||
#--------------------------------------------------
|
||||
echo -e "\n---- Groupe base-devel (compilateur C, make…) ----"
|
||||
${PAC} base-devel
|
||||
retVal=$?
|
||||
if [[ $retVal -ne 0 ]]; then
|
||||
echo "pacman base-devel installation error."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#--------------------------------------------------
|
||||
# Dépendances de build pyenv (compilation de CPython) + outils de base
|
||||
#--------------------------------------------------
|
||||
echo -e "\n---- Dépendances pyenv (compilation Python) + outils ----"
|
||||
${PAC} git wget curl openssl zlib xz tk bzip2 readline sqlite libffi
|
||||
retVal=$?
|
||||
if [[ $retVal -ne 0 ]]; then
|
||||
echo "pacman pyenv dependencies installation error."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#--------------------------------------------------
|
||||
# PostgreSQL (+ PostGIS) — Arch n'initialise pas le cluster automatiquement
|
||||
#--------------------------------------------------
|
||||
echo -e "\n---- Install PostgreSQL Server ----"
|
||||
${PAC} postgresql
|
||||
retVal=$?
|
||||
if [[ $retVal -ne 0 ]]; then
|
||||
echo "pacman postgresql installation error."
|
||||
exit 1
|
||||
fi
|
||||
# Initialisation du cluster (chemin Arch : /var/lib/postgres/data).
|
||||
if [ ! -f /var/lib/postgres/data/PG_VERSION ]; then
|
||||
echo -e "\n---- Initialisation du cluster PostgreSQL ----"
|
||||
sudo -u postgres initdb --locale=C.UTF-8 --encoding=UTF8 \
|
||||
-D /var/lib/postgres/data || true
|
||||
fi
|
||||
sudo systemctl enable --now postgresql 2>/dev/null || true
|
||||
# PostGIS : optionnel (géospatial), ne bloque pas.
|
||||
${PAC} 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
|
||||
|
||||
echo -e "\n---- Update NPM ----"
|
||||
install_package npm
|
||||
#--------------------------------------------------
|
||||
# Dépendances Odoo / ERPLibre (extensions Python, bindings)
|
||||
#--------------------------------------------------
|
||||
echo -e "\n---- Installing arch dependency ----"
|
||||
# best-effort paquet par paquet : pacman refuse TOUTE la transaction si UN
|
||||
# seul nom est inconnu (pas de --skip-unavailable). Ces deps ne sont pas
|
||||
# critiques pour le build Python -> on ne bloque pas sur un nom absent.
|
||||
for _pkg in libxslt libzip libldap libsasl cmake parallel swig portaudio \
|
||||
cups xmlsec freetds libev mariadb-libs shfmt; do
|
||||
${PAC} "${_pkg}" || echo " ${_pkg} : non installé (optionnel), on continue."
|
||||
done
|
||||
# libldap_r : Odoo/python-ldap cherche parfois libldap_r.so (supprimé des
|
||||
# versions récentes d'OpenLDAP) -> lien vers libldap.so.
|
||||
sudo ln -fs /usr/lib/libldap.so /usr/lib/libldap_r.so 2>/dev/null || true
|
||||
|
||||
sudo npm install npm@latest -g
|
||||
#--------------------------------------------------
|
||||
# Node.js + npm (rtlcss, less)
|
||||
#--------------------------------------------------
|
||||
echo -e "\n---- Installing nodeJS NPM and rtlcss ----"
|
||||
${PAC} nodejs npm
|
||||
retVal=$?
|
||||
if [[ $retVal -ne 0 ]]; then
|
||||
echo "npm install npm lastest installation error."
|
||||
exit 1
|
||||
fi
|
||||
sudo npm install -g rtlcss
|
||||
retVal=$?
|
||||
if [[ $retVal -ne 0 ]]; then
|
||||
echo "npm install rtlcss installation error."
|
||||
exit 1
|
||||
fi
|
||||
sudo npm install -g less
|
||||
retVal=$?
|
||||
if [[ $retVal -ne 0 ]]; then
|
||||
echo "npm install less installation error."
|
||||
echo "pacman 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
|
||||
retVal=$?
|
||||
if [[ $retVal -ne 0 ]]; then
|
||||
echo "npm install prettier + plugin-xml installation error."
|
||||
exit 1
|
||||
npm install || echo "npm install (prettier/plugin-xml): erreur (optionnel)."
|
||||
|
||||
# Pour erplibre_devops.
|
||||
${PAC} sshpass || echo "sshpass non installé (optionnel)."
|
||||
|
||||
#--------------------------------------------------
|
||||
# nginx (optionnel)
|
||||
#--------------------------------------------------
|
||||
if [ "${EL_INSTALL_NGINX}" = "True" ]; then
|
||||
echo -e "\n---- Installing nginx ----"
|
||||
${PAC} nginx || echo "nginx: erreur (optionnel)."
|
||||
fi
|
||||
|
||||
# TODO install nginx
|
||||
|
||||
# ERPLibre installation
|
||||
install_package cmake
|
||||
install_package parallel
|
||||
install_package tk
|
||||
install_package shfmt
|
||||
|
||||
# For erplibre_devops
|
||||
install_package sshpass
|
||||
#--------------------------------------------------
|
||||
# wkhtmltopdf (optionnel) — uniquement dans l'AUR sur Arch (pas de paquet
|
||||
# officiel). Sur une image cloud sans helper AUR, on saute proprement.
|
||||
#--------------------------------------------------
|
||||
if [ "${EL_INSTALL_WKHTMLTOPDF}" = "True" ]; then
|
||||
if ! command -v wkhtmltopdf >/dev/null 2>&1; then
|
||||
echo "wkhtmltopdf : disponible seulement via l'AUR sur Arch, ignoré"
|
||||
echo " (installez-le manuellement avec un helper AUR si nécessaire)."
|
||||
else
|
||||
echo -e "\n---- Already installed wkhtml ----"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo -e "\n---- Arch Linux dependency installation done ----"
|
||||
|
|
|
|||
|
|
@ -5,6 +5,11 @@
|
|||
EL_USER=${USER}
|
||||
#EL_INSTALL_WKHTMLTOPDF="True"
|
||||
|
||||
# apt-get qui ATTEND le verrou (jusqu'à 10 min) : sur une image cloud fraîche,
|
||||
# cloud-init / unattended-upgrades tiennent souvent le verrou apt au 1er boot
|
||||
# (« Could not get lock » -> échec de l'install). DPkg::Lock::Timeout patiente.
|
||||
APT_GET="sudo apt-get -o DPkg::Lock::Timeout=600"
|
||||
|
||||
##
|
||||
### WKHTMLTOPDF download links
|
||||
## === Ubuntu Focal x64 === (for other distributions please replace these two links,
|
||||
|
|
@ -15,22 +20,30 @@ UBUNTU_VERSION=$(lsb_release -rs)
|
|||
DEBIAN_VERSION=$(lsb_release -cs)
|
||||
OS=$(lsb_release -si)
|
||||
if [[ "${OS}" == "Ubuntu" ]]; then
|
||||
if [ "25.10" == "${UBUNTU_VERSION}" ] || [ "25.04" == "${UBUNTU_VERSION}" ] || [ "24.04" == "${UBUNTU_VERSION}" ] || [ "24.10" == "${UBUNTU_VERSION}" ] || [ "23.10" == "${UBUNTU_VERSION}" ] || [ "23.04" == "${UBUNTU_VERSION}" ] || [ "22.10" == "${UBUNTU_VERSION}" ] || [ "22.04" == "${UBUNTU_VERSION}" ]; then
|
||||
WKHTMLTOX_X64=https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-3/wkhtmltox_0.12.6.1-3.jammy_amd64.deb
|
||||
elif [ "20.04" == "${UBUNTU_VERSION}" ]; then
|
||||
if [ "20.04" == "${UBUNTU_VERSION}" ]; then
|
||||
WKHTMLTOX_X64=https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox_0.12.6-1.focal_amd64.deb
|
||||
elif [ "18.04" == "${UBUNTU_VERSION}" ]; then
|
||||
WKHTMLTOX_X64=https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox_0.12.6-1.bionic_amd64.deb
|
||||
else
|
||||
# 22.04+ (jusqu'à 26.04 et au-delà) : wkhtmltopdf ne publie pas de build
|
||||
# par version ; le .deb « jammy » est le plus récent et fonctionne. Un
|
||||
# « else » (au lieu d'énumérer les versions) évite une URL VIDE sur une
|
||||
# version récente (26.04) -> gdebi appelé sans fichier -> échec.
|
||||
WKHTMLTOX_X64=https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-3/wkhtmltox_0.12.6.1-3.jammy_amd64.deb
|
||||
fi
|
||||
elif [[ "${OS}" == "Linuxmint" ]]; then
|
||||
if [ "22.3" == "${UBUNTU_VERSION}" ]; then
|
||||
WKHTMLTOX_X64=https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-3/wkhtmltox_0.12.6.1-3.jammy_amd64.deb
|
||||
fi
|
||||
elif [[ "${OS}" == "Debian" ]]; then
|
||||
if [ "bookworm" == "${DEBIAN_VERSION}" ]; then
|
||||
WKHTMLTOX_X64=https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-3/wkhtmltox_0.12.6.1-3.bookworm_amd64.deb
|
||||
else
|
||||
if [ "bullseye" == "${DEBIAN_VERSION}" ]; then
|
||||
WKHTMLTOX_X64=https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-3/wkhtmltox_0.12.6.1-3.bullseye_amd64.deb
|
||||
else
|
||||
# bookworm (12), trixie (13) et au-delà : wkhtmltopdf ne publie pas de
|
||||
# build au-delà de « bookworm » -> on prend bookworm (le plus récent).
|
||||
# Le build « bullseye » (Debian 11) échouait à s'installer sur trixie
|
||||
# (gdebi : dépendances incompatibles).
|
||||
WKHTMLTOX_X64=https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-3/wkhtmltox_0.12.6.1-3.bookworm_amd64.deb
|
||||
fi
|
||||
elif [[ "${OS}" == *"Ubuntu"* ]]; then
|
||||
echo "Your version of Ubuntu is not supported, only support 18.04, 20.04 and 22.04"
|
||||
|
|
@ -55,25 +68,30 @@ echo -e "\n---- Update Server ----"
|
|||
|
||||
if [ "18.04" == "${UBUNTU_VERSION}" ]; then
|
||||
# add-apt-repository can install add-apt-repository Ubuntu 18.x
|
||||
sudo apt-get install software-properties-common curl -y
|
||||
${APT_GET} install software-properties-common curl -y
|
||||
# universe package is for Ubuntu 18.x
|
||||
sudo add-apt-repository universe
|
||||
# libpng12-0 dependency for wkhtmltopdf
|
||||
sudo add-apt-repository "deb http://mirrors.kernel.org/ubuntu/ xenial main"
|
||||
sudo apt-get update
|
||||
sudo apt-get upgrade -y
|
||||
${APT_GET} update
|
||||
${APT_GET} upgrade -y
|
||||
fi
|
||||
|
||||
#--------------------------------------------------
|
||||
# Install PostgreSQL Server
|
||||
#--------------------------------------------------
|
||||
echo -e "\n---- Install PostgreSQL Server ----"
|
||||
sudo apt-get install postgresql libpq-dev postgis -y
|
||||
${APT_GET} install postgresql postgresql-contrib libpq-dev -y
|
||||
retVal=$?
|
||||
if [[ $retVal -ne 0 ]]; then
|
||||
echo "apt-get install postgresql installation error."
|
||||
exit 1
|
||||
fi
|
||||
# PostGIS : optionnel (géospatial). Le nom du paquet « postgis » n'existe pas
|
||||
# sur toutes les versions (Ubuntu 24.04) -> best-effort, ne bloque pas.
|
||||
${APT_GET} install postgis -y \
|
||||
|| ${APT_GET} install postgresql-postgis -y \
|
||||
|| 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
|
||||
|
|
@ -82,20 +100,27 @@ sudo su - postgres -c "createuser -s ${EL_USER}" 2>/dev/null || true
|
|||
# Install Dependencies
|
||||
#--------------------------------------------------
|
||||
echo -e "\n--- Installing debian dependency --"
|
||||
sudo apt-get install git build-essential wget libxslt-dev libzip-dev libldap2-dev libsasl2-dev gdebi-core libffi-dev libbz2-dev parallel pysassc swig cmake portaudio19-dev libcups2-dev shfmt xmlsec1 -y
|
||||
${APT_GET} install git build-essential wget libxslt-dev libzip-dev libldap2-dev libsasl2-dev gdebi-core libffi-dev libbz2-dev parallel pysassc swig cmake portaudio19-dev libcups2-dev xmlsec1 -y
|
||||
retVal=$?
|
||||
if [[ $retVal -ne 0 ]]; then
|
||||
echo "apt-get debian tool installation error."
|
||||
exit 1
|
||||
fi
|
||||
sudo apt-get install libmariadbd-dev freetds-dev -y
|
||||
# shfmt : ABSENT des dépôts Ubuntu < 22.04. Il était dans le lot critique
|
||||
# ci-dessus -> un seul paquet introuvable faisait échouer TOUT l'apt-get
|
||||
# (donc pas de build-essential/gcc -> pyenv ne pouvait plus compiler Python).
|
||||
# C'est un simple formateur shell (dev), non requis pour exécuter ERPLibre :
|
||||
# on l'installe SÉPARÉMENT et en best-effort (jamais fatal).
|
||||
${APT_GET} install shfmt -y \
|
||||
|| echo "shfmt indisponible dans les dépôts (Ubuntu < 22.04 ?) — ignoré."
|
||||
${APT_GET} install libmariadbd-dev freetds-dev -y
|
||||
retVal=$?
|
||||
if [[ $retVal -ne 0 ]]; then
|
||||
echo "apt-get libmariadb installation error."
|
||||
exit 1
|
||||
fi
|
||||
if [ "18.04" == "${UBUNTU_VERSION}" ]; then
|
||||
sudo apt-get install libpng12-0 -y
|
||||
${APT_GET} install libpng12-0 -y
|
||||
retVal=$?
|
||||
if [[ $retVal -ne 0 ]]; then
|
||||
echo "apt-get libpng installation error."
|
||||
|
|
@ -103,14 +128,14 @@ if [ "18.04" == "${UBUNTU_VERSION}" ]; then
|
|||
fi
|
||||
fi
|
||||
# Dependencies for pyenv
|
||||
sudo apt-get install make libssl-dev zlib1g-dev libreadline-dev libsqlite3-dev curl llvm libncurses5-dev libncursesw5-dev xz-utils tk-dev liblzma-dev -y
|
||||
${APT_GET} install make libssl-dev zlib1g-dev libreadline-dev libsqlite3-dev curl llvm libncurses5-dev libncursesw5-dev xz-utils tk-dev liblzma-dev -y
|
||||
retVal=$?
|
||||
if [[ $retVal -ne 0 ]]; then
|
||||
echo "apt-get pyenv dependencies installation error."
|
||||
exit 1
|
||||
fi
|
||||
# Dependencies for selenium
|
||||
sudo apt-get install libcairo2-dev python3-dev pkg-config libxt-dev libgirepository1.0-dev -y
|
||||
${APT_GET} install libcairo2-dev python3-dev pkg-config libxt-dev libgirepository1.0-dev -y
|
||||
retVal=$?
|
||||
if [[ $retVal -ne 0 ]]; then
|
||||
echo "apt-get selenium dependencies installation error."
|
||||
|
|
@ -118,8 +143,8 @@ if [[ $retVal -ne 0 ]]; then
|
|||
fi
|
||||
|
||||
echo -e "\n---- Installing nodeJS NPM and rtlcss for LTR support ----"
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y ca-certificates curl gnupg
|
||||
${APT_GET} update
|
||||
${APT_GET} install -y ca-certificates curl gnupg
|
||||
sudo mkdir -p /etc/apt/keyrings
|
||||
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg
|
||||
|
||||
|
|
@ -132,8 +157,8 @@ else
|
|||
fi
|
||||
|
||||
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | sudo tee /etc/apt/sources.list.d/nodesource.list
|
||||
sudo apt-get update
|
||||
sudo apt-get install nodejs -y
|
||||
${APT_GET} update
|
||||
${APT_GET} install nodejs -y
|
||||
|
||||
sudo npm install npm@latest -g
|
||||
retVal=$?
|
||||
|
|
@ -177,21 +202,36 @@ fi
|
|||
#--------------------------------------------------
|
||||
# Install Wkhtmltopdf if needed
|
||||
#--------------------------------------------------
|
||||
if [ ${EL_INSTALL_WKHTMLTOPDF} = "True" ]; then
|
||||
if [ "$(uname -m)" != "x86_64" ]; then
|
||||
# WKHTMLTOX_X64 pointe vers un .deb amd64 : sur toute autre architecture
|
||||
# (s390x, arm64/aarch64…) gdebi échouerait. On saute proprement plutôt que
|
||||
# d'avorter tout l'install (wkhtmltopdf est optionnel).
|
||||
echo "wkhtmltopdf : pas de build pour $(uname -m), ignoré (optionnel)."
|
||||
elif [ ${EL_INSTALL_WKHTMLTOPDF} = "True" ]; then
|
||||
echo -e "\n---- Installing wkhtml ----"
|
||||
INSTALLED=$(dpkg -s wkhtmltox | grep installed)
|
||||
if [ "" == "${INSTALLED}" ]; then
|
||||
echo -e "\n---- Install wkhtml and place shortcuts on correct place ----"
|
||||
_url=${WKHTMLTOX_X64}
|
||||
sudo wget ${_url}
|
||||
sudo gdebi --n $(basename ${_url})
|
||||
retVal=$?
|
||||
if [[ $retVal -ne 0 ]]; then
|
||||
echo "gdebi install wkhtmltopdf installation error."
|
||||
exit 1
|
||||
if [ -z "${_url}" ]; then
|
||||
# Aucune URL (version non mappée) : wkhtmltopdf est OPTIONNEL, on saute
|
||||
# proprement plutôt que d'appeler gdebi sans fichier (« Usage: gdebi »).
|
||||
echo "wkhtmltopdf : aucune URL pour cette version, ignoré (optionnel)."
|
||||
else
|
||||
sudo wget ${_url}
|
||||
sudo gdebi --n $(basename ${_url})
|
||||
retVal=$?
|
||||
if [[ $retVal -ne 0 ]]; then
|
||||
# wkhtmltopdf est OPTIONNEL (rapports PDF). NON bloquant : sur Debian
|
||||
# 13 (trixie) le .deb dépendait de libssl1.1 (absent) et « exit 1 »
|
||||
# faisait échouer TOUT install_os -> Odoo jamais installé. On avertit
|
||||
# et on continue (comme Arch qui poursuit sans wkhtmltopdf).
|
||||
echo "wkhtmltopdf : installation échouée, ignoré (optionnel — pas de PDF)."
|
||||
else
|
||||
sudo ln -fs /usr/local/bin/wkhtmltopdf /usr/bin
|
||||
sudo ln -fs /usr/local/bin/wkhtmltoimage /usr/bin
|
||||
fi
|
||||
fi
|
||||
sudo ln -fs /usr/local/bin/wkhtmltopdf /usr/bin
|
||||
sudo ln -fs /usr/local/bin/wkhtmltoimage /usr/bin
|
||||
else
|
||||
echo -e "\n---- Already installed wkhtml ----"
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -3,11 +3,11 @@
|
|||
if [[ "${OSTYPE}" == "linux-gnu" ]]; then
|
||||
source /etc/os-release
|
||||
if [[ "${ID}" == "ubuntu" ]]; then
|
||||
if [[ "${VERSION_ID}" == "18.04" || "${VERSION_ID}" == "20.04" || "${VERSION_ID}" == "22.04" || "${VERSION_ID}" == "22.10" || "${VERSION_ID}" == "23.04" || "${VERSION_ID}" == "23.10" || "${VERSION_ID}" == "24.04" || "${VERSION_ID}" == "25.04" || "${VERSION_ID}" == "25.10" ]]; then
|
||||
if [[ "${VERSION_ID}" == "18.04" || "${VERSION_ID}" == "20.04" || "${VERSION_ID}" == "22.04" || "${VERSION_ID}" == "22.10" || "${VERSION_ID}" == "23.04" || "${VERSION_ID}" == "23.10" || "${VERSION_ID}" == "24.04" || "${VERSION_ID}" == "25.04" || "${VERSION_ID}" == "25.10" || "${VERSION_ID}" == "26.04" ]]; then
|
||||
echo "\n---- linux-gnu installation process started ----"
|
||||
./script/install/install_debian_dependency.sh
|
||||
else
|
||||
echo "Your version is not supported, only support 18.04, 20.04 and 22.04 - 24.04, 25.04, 25.10 : ${VERSION_ID}"
|
||||
echo "Your version is not supported, only support 18.04, 20.04 and 22.04 - 24.04, 25.04, 25.10, 26.04 : ${VERSION_ID}"
|
||||
fi
|
||||
elif [[ "${ID}" == "linuxmint" ]]; then
|
||||
if [[ "${VERSION_ID}" == "22.3" ]]; then
|
||||
|
|
@ -20,9 +20,12 @@ if [[ "${OSTYPE}" == "linux-gnu" ]]; then
|
|||
./script/install/install_debian_dependency.sh
|
||||
elif [[ "${ID}" == "arch" ]]; then
|
||||
./script/install/install_arch_linux.sh
|
||||
elif [[ "${ID}" == "fedora" || "${ID_LIKE}" == *"fedora"* || "${ID_LIKE}" == *"rhel"* ]]; then
|
||||
echo "\n---- Fedora installation process started ----"
|
||||
./script/install/install_fedora_dependency.sh
|
||||
else
|
||||
./script/install/install_debian_dependency.sh
|
||||
echo "Your Linux system is not supported, only support Ubuntu 18.04 or Ubuntu 20.04 or Ubuntu 22.04 - Ubuntu 23.10 - Ubuntu 24.04, Ubuntu 25.04, Ubuntu 25.10 ."
|
||||
echo "Your Linux system is not supported, only support Ubuntu 18.04 or Ubuntu 20.04 or Ubuntu 22.04 - Ubuntu 23.10 - Ubuntu 24.04, Ubuntu 25.04, Ubuntu 25.10, Debian, Fedora, Arch."
|
||||
fi
|
||||
elif [[ "${OSTYPE}" == "darwin"* ]]; then
|
||||
echo "\n---- Darwin installation process started ----"
|
||||
|
|
|
|||
129
script/install/install_fedora_dependency.sh
Executable file
129
script/install/install_fedora_dependency.sh
Executable file
|
|
@ -0,0 +1,129 @@
|
|||
#!/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 Fedora (dnf). Équivalent Fedora de
|
||||
# install_debian_dependency.sh. « --skip-unavailable » tolère un nom de paquet
|
||||
# absent (dnf5) au lieu d'échouer sur tout le lot.
|
||||
|
||||
. ./env_var.sh
|
||||
|
||||
EL_USER=${USER}
|
||||
|
||||
# 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 --skip-unavailable"
|
||||
|
||||
#--------------------------------------------------
|
||||
# Outils de compilation (build Python via pyenv, extensions Python)
|
||||
#--------------------------------------------------
|
||||
echo -e "\n---- Groupe outils de développement ----"
|
||||
# Groupes par ID (le nom affiché « C Development Tools... » n'est pas matché).
|
||||
sudo dnf group install -y --skip-unavailable development-tools c-development \
|
||||
|| sudo dnf install -y gcc gcc-c++ make automake patch
|
||||
|
||||
#--------------------------------------------------
|
||||
# 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 ----"
|
||||
|
|
@ -96,6 +96,12 @@ if [[ "${EL_PHASE}" != "setup" ]]; then
|
|||
retVal=$?
|
||||
if [[ $retVal -ne 0 ]]; then
|
||||
echo "Poetry installation error with status ${retVal}"
|
||||
# « -q » masque la CAUSE. On rejoue en « -vvv » (debug) car c'est
|
||||
# le SEUL niveau où Poetry affiche la sortie des sous-processus
|
||||
# (git clone/checkout, build pip) — donc l'erreur réelle d'une
|
||||
# dépendance VCS/build. Capturé dans le log pour diagnostic.
|
||||
echo "---- Poetry: rejeu -vvv pour diagnostic ----"
|
||||
poetry install --no-root -vvv 2>&1 || true
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -12,9 +12,22 @@ fi
|
|||
#EL_MANIFEST_PROD="./default.xml"
|
||||
#EL_MANIFEST_DEV="./manifest/default.dev.xml"
|
||||
|
||||
# Update git-repo
|
||||
# Update git-repo : local git daemon serving the repo over git://127.0.0.1:9418.
|
||||
# Kill any leftover daemon from a previous (interrupted) run first: otherwise the
|
||||
# stale server keeps port 9418, the new daemon fails to bind ("Address already in
|
||||
# use"), and the cleanup kill below fails on an already-dead PID -> script exit 1.
|
||||
# Match on the stable arguments, not "git daemon": « git daemon » execs into
|
||||
# « git-daemon » (hyphen, /usr/lib/git-core/git-daemon), so "git daemon" (space)
|
||||
# never matches the actual running process.
|
||||
if pkill -f "daemon --base-path=. --export-all" 2>/dev/null; then
|
||||
sleep 1 # let the kernel release port 9418 before we rebind
|
||||
fi
|
||||
|
||||
git daemon --base-path=. --export-all --reuseaddr --informative-errors ${DAEMON_VERBOSE} &
|
||||
DAEMON_PID=$!
|
||||
# Always stop the daemon we started, whatever happens next (success or error),
|
||||
# without ever failing the script if it is already gone.
|
||||
trap 'kill "${DAEMON_PID}" 2>/dev/null || true' EXIT
|
||||
|
||||
if [ -L "$EL_MANIFEST_DEV" ]; then
|
||||
MANIFEST_TARGET=$(readlink -f "$EL_MANIFEST_DEV")
|
||||
|
|
@ -34,4 +47,4 @@ fi
|
|||
.venv.erplibre/bin/repo init -u git://127.0.0.1:9418/ -b $(git rev-parse --verify HEAD) -m ${MANIFEST_TARGET} "$@"
|
||||
.venv.erplibre/bin/repo sync -c -j "$JOBS" ${REPO_VERBOSE} -m ${MANIFEST_TARGET}
|
||||
|
||||
kill ${DAEMON_PID}
|
||||
# Daemon cleanup handled by the EXIT trap above (tolerant of an already-dead PID).
|
||||
|
|
|
|||
|
|
@ -14,6 +14,10 @@ import time
|
|||
|
||||
# erplibre_state is in the same directory; import lazily to avoid hard failure
|
||||
# when the script runs outside the project root (e.g. during bare install).
|
||||
# Two import styles are needed: when this file is imported as a package module
|
||||
# the repo root is on sys.path (package import works); when it is executed
|
||||
# directly as ./script/version/update_env_version.py, sys.path[0] is
|
||||
# script/version/ and only the sibling import resolves.
|
||||
try:
|
||||
from script.version.erplibre_state import (
|
||||
get_version_extra,
|
||||
|
|
@ -25,7 +29,18 @@ try:
|
|||
|
||||
_STATE_AVAILABLE = True
|
||||
except ImportError:
|
||||
_STATE_AVAILABLE = False
|
||||
try:
|
||||
from erplibre_state import (
|
||||
get_version_extra,
|
||||
get_version_installed,
|
||||
print_state,
|
||||
set_version_installed,
|
||||
set_version_switched,
|
||||
)
|
||||
|
||||
_STATE_AVAILABLE = True
|
||||
except ImportError:
|
||||
_STATE_AVAILABLE = False
|
||||
|
||||
logging.basicConfig(level=os.environ.get("LOGLEVEL", "INFO"))
|
||||
|
||||
|
|
@ -546,6 +561,61 @@ class Update:
|
|||
self.execute_log.append("Extra modules (CybroOdoo)")
|
||||
return os.system("./script/manifest/update_manifest_local_dev.sh")
|
||||
|
||||
def add_extra_to_config_conf(self):
|
||||
"""Append the extra addons (CybroOdoo, ...) to config.conf addons_path.
|
||||
|
||||
generate_config.sh rewrites config.conf from a fixed addons list that
|
||||
does NOT include the extra modules, so this must run AFTER it (last
|
||||
writer wins). The paths come from the source-of-truth extra manifest
|
||||
(projects tagged with the "extra" group). Already-present paths are
|
||||
skipped, so the call is idempotent."""
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
ver = self.new_version_odoo # e.g. "18.0"
|
||||
manifest = os.path.join(
|
||||
"manifest", f"git_manifest_extra_odoo{ver}.xml"
|
||||
)
|
||||
config_path = "config.conf"
|
||||
if not os.path.isfile(manifest) or not os.path.isfile(config_path):
|
||||
_logger.warning(
|
||||
"Cannot add extra modules to config.conf:"
|
||||
f" missing {manifest} or {config_path}."
|
||||
)
|
||||
return
|
||||
home = os.getcwd()
|
||||
prefix = f"odoo{ver}/addons/"
|
||||
extra_paths = []
|
||||
for project in ET.parse(manifest).getroot().findall("project"):
|
||||
groups = project.get("groups", "").split(",")
|
||||
path = project.get("path", "")
|
||||
if "extra" in groups and path.startswith(prefix):
|
||||
extra_paths.append(os.path.join(home, path))
|
||||
if not extra_paths:
|
||||
return
|
||||
|
||||
with open(config_path, "r", encoding="utf-8") as f:
|
||||
lines = f.readlines()
|
||||
changed = False
|
||||
for i, line in enumerate(lines):
|
||||
if not line.startswith("addons_path"):
|
||||
continue
|
||||
value = line.rstrip("\n").split("=", 1)[1] if "=" in line else ""
|
||||
existing = [p.strip() for p in value.split(",") if p.strip()]
|
||||
missing = [p for p in extra_paths if p not in existing]
|
||||
if missing:
|
||||
lines[i] = "addons_path = " + ",".join(existing + missing) + "\n"
|
||||
changed = True
|
||||
break
|
||||
if changed:
|
||||
with open(config_path, "w", encoding="utf-8") as f:
|
||||
f.writelines(lines)
|
||||
_logger.info(
|
||||
"Added extra addons to config.conf: "
|
||||
+ ", ".join(extra_paths)
|
||||
)
|
||||
else:
|
||||
_logger.info("Extra addons already present in config.conf.")
|
||||
|
||||
def install_system(self):
|
||||
self.execute_log.append(f"System installation")
|
||||
status = os.system("./script/install/install_dev.sh")
|
||||
|
|
@ -779,6 +849,13 @@ def main():
|
|||
)
|
||||
os.system("./script/generate_config.sh")
|
||||
|
||||
# config.conf : generate_config.sh (ci-dessus) réécrit le fichier à partir
|
||||
# d'une liste d'addons figée SANS les modules extra ; on ajoute donc les
|
||||
# chemins extra APRÈS coup (dernier writer). Idempotent, sans effet si
|
||||
# --with_extra n'est pas demandé.
|
||||
if update.config.with_extra and exit_code == 0:
|
||||
update.add_extra_to_config_conf()
|
||||
|
||||
return exit_code
|
||||
# TODO ignore this if installation fail
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue