diff --git a/.claude/rules/08-deployment.md b/.claude/rules/08-deployment.md index a928e1a..e4ad023 100644 --- a/.claude/rules/08-deployment.md +++ b/.claude/rules/08-deployment.md @@ -7,7 +7,8 @@ - **DNS** : `script/deployment/update_dns_cloudflare.py` Plateformes supportées : Ubuntu 24.04 / 25.10 / 26.04, Linux Mint 22.3, -Debian 12, AlmaLinux 9+, Rocky Linux 9+, openSUSE Tumbleweed, Arch Linux, +Debian 12, AlmaLinux 9+, Rocky Linux 9+, openSUSE Leap 16 et Tumbleweed, +Arch Linux, macOS (mise ou pyenv), Windows (WSL/Docker). diff --git a/script/install/install_suse_dependency.sh b/script/install/install_suse_dependency.sh index e9c86cc..8170bf5 100755 --- a/script/install/install_suse_dependency.sh +++ b/script/install/install_suse_dependency.sh @@ -5,9 +5,13 @@ # Dépendances système ERPLibre pour la famille SUSE (zypper). Équivalent SUSE # de install_debian_dependency.sh et install_fedora_dependency.sh. # -# Visé : openSUSE Tumbleweed, la seule distribution du catalogue dont qpdf -# (12.3.2) dépasse déjà le seuil de pikepdf 10 — la compilation de qpdf, une -# demi-heure sous émulation s390x, ne s'y déclenche pas. +# Visé : openSUSE Leap 16 (le défaut, numéroté et stable) et Tumbleweed (la +# rolling, gardée comme banc d'essai). Les deux livrent un qpdf au-dessus du +# seuil de pikepdf 10 — la compilation de qpdf, une demi-heure sous émulation +# s390x, ne s'y déclenche pas. +# +# Ce qui les sépare dans ce script tient en deux points, tous deux marqués par +# SUSE_ROLLING : le chemin des dépôts, et « dup » contre « up ». . ./env_var.sh . ./script/install/lib_qpdf.sh @@ -148,8 +152,17 @@ sudo zypper --non-interactive refresh || true # réclamait un perl-Git bâti contre un perl-base plus ancien que celui de # l'image. zypper proposait alors trois solutions et ATTENDAIT un choix ; # « --non-interactive » prend le défaut, « c » = annuler, et tout s'arrêtait. -echo -e "\n---- Mise a jour complete (dup) ----" -${ZYP} dup ${ZYP_LIC} --allow-vendor-change || true +if [ "${SUSE_ROLLING}" = 1 ]; then + echo -e "\n---- Mise a jour complete (dup) ----" + ${ZYP} dup ${ZYP_LIC} --allow-vendor-change || true +else + # Sur Leap, « dup » sert à CHANGER de version, pas à mettre à jour : l'y + # appeler alignerait la machine sur ce que les dépôts contiennent, ce qui + # n'est pas ce qu'on veut d'une distribution justement choisie pour ne pas + # bouger. « up » suffit, l'image et ses dépôts étant de la même version. + echo -e "\n---- Mise a jour (up) ----" + ${ZYP} up ${ZYP_LIC} || true +fi #-------------------------------------------------- # Outils de compilation (build Python via pyenv, extensions Python) diff --git a/script/qemu/README.base.md b/script/qemu/README.base.md index 19fef19..b031ad7 100644 --- a/script/qemu/README.base.md +++ b/script/qemu/README.base.md @@ -182,15 +182,19 @@ Catalog, per architecture (`deploy_qemu.py` is the source of truth): | fedora | `41`, `42` (default), `43`, `44` | ✔ | ✔ | `43` only | | almalinux | `9` (default), `10` | ✔ | ✔ | ✔ | | rocky | `9`, `10` (default) | ✔ | ✔ | ✔ | -| opensuse | `tumbleweed` | ✔ | ✔ | ✔ | +| opensuse | `16.0` (default), `tumbleweed` | ✔ | ✔ | ✔ | | arch | `latest` | ✔ | — | — | Fedora builds s390x only for the current release, and on a separate tree (`fedora-secondary`) — hence the single version there. -`opensuse` is openSUSE Tumbleweed, the only entry whose qpdf (12.3.2) already -clears the pikepdf threshold: the half-hour qpdf build never runs there, which -matters under s390x emulation. +`opensuse` covers two distinct products, not two versions of one. Leap `16.0` +is numbered and stable (SLE base) and is the default. `tumbleweed` is the +rolling one, kept as a bellwether for breakage to come: its snapshot drift is +real, and it demands a full `zypper dup` before anything can be installed. + +Both ship a qpdf above the pikepdf threshold, so the half-hour qpdf build +never runs there — which matters under s390x emulation. Provide an explicit image path as a positional argument to override the automatic download location. @@ -212,15 +216,21 @@ Catalogue, par architecture (`deploy_qemu.py` fait autorité) : | fedora | `41`, `42` (défaut), `43`, `44` | ✔ | ✔ | `43` seule | | almalinux | `9` (défaut), `10` | ✔ | ✔ | ✔ | | rocky | `9`, `10` (défaut) | ✔ | ✔ | ✔ | -| opensuse | `tumbleweed` | ✔ | ✔ | ✔ | +| opensuse | `16.0` (défaut), `tumbleweed` | ✔ | ✔ | ✔ | | arch | `latest` | ✔ | — | — | Fedora ne construit s390x que pour la version courante, et sur une arborescence à part (`fedora-secondary`) — d'où la version unique. -`opensuse` désigne openSUSE Tumbleweed, seule entrée dont qpdf (12.3.2) -dépasse déjà le seuil de pikepdf : la compilation de qpdf, une demi-heure, ne -s'y déclenche jamais — ce qui compte sous émulation s390x. +`opensuse` recouvre deux produits distincts, pas deux versions du même. Leap +`16.0` est numérotée et stable (base SLE) : c'est le défaut. `tumbleweed` est +la rolling, gardée comme banc d'essai des ruptures à venir — sa dérive +d'instantanés est réelle, et elle impose un `zypper dup` complet avant toute +installation. + +Les deux livrent un qpdf au-dessus du seuil de pikepdf : la compilation de +qpdf, une demi-heure, ne s'y déclenche jamais — ce qui compte sous émulation +s390x. Fournissez un chemin d'image en argument positionnel pour surcharger l'emplacement de téléchargement automatique. diff --git a/script/qemu/README.fr.md b/script/qemu/README.fr.md index 52c68ae..af7b826 100644 --- a/script/qemu/README.fr.md +++ b/script/qemu/README.fr.md @@ -101,15 +101,21 @@ Catalogue, par architecture (`deploy_qemu.py` fait autorité) : | fedora | `41`, `42` (défaut), `43`, `44` | ✔ | ✔ | `43` seule | | almalinux | `9` (défaut), `10` | ✔ | ✔ | ✔ | | rocky | `9`, `10` (défaut) | ✔ | ✔ | ✔ | -| opensuse | `tumbleweed` | ✔ | ✔ | ✔ | +| opensuse | `16.0` (défaut), `tumbleweed` | ✔ | ✔ | ✔ | | arch | `latest` | ✔ | — | — | Fedora ne construit s390x que pour la version courante, et sur une arborescence à part (`fedora-secondary`) — d'où la version unique. -`opensuse` désigne openSUSE Tumbleweed, seule entrée dont qpdf (12.3.2) -dépasse déjà le seuil de pikepdf : la compilation de qpdf, une demi-heure, ne -s'y déclenche jamais — ce qui compte sous émulation s390x. +`opensuse` recouvre deux produits distincts, pas deux versions du même. Leap +`16.0` est numérotée et stable (base SLE) : c'est le défaut. `tumbleweed` est +la rolling, gardée comme banc d'essai des ruptures à venir — sa dérive +d'instantanés est réelle, et elle impose un `zypper dup` complet avant toute +installation. + +Les deux livrent un qpdf au-dessus du seuil de pikepdf : la compilation de +qpdf, une demi-heure, ne s'y déclenche jamais — ce qui compte sous émulation +s390x. Fournissez un chemin d'image en argument positionnel pour surcharger l'emplacement de téléchargement automatique. diff --git a/script/qemu/README.md b/script/qemu/README.md index cda760f..473a847 100644 --- a/script/qemu/README.md +++ b/script/qemu/README.md @@ -95,15 +95,19 @@ Catalog, per architecture (`deploy_qemu.py` is the source of truth): | fedora | `41`, `42` (default), `43`, `44` | ✔ | ✔ | `43` only | | almalinux | `9` (default), `10` | ✔ | ✔ | ✔ | | rocky | `9`, `10` (default) | ✔ | ✔ | ✔ | -| opensuse | `tumbleweed` | ✔ | ✔ | ✔ | +| opensuse | `16.0` (default), `tumbleweed` | ✔ | ✔ | ✔ | | arch | `latest` | ✔ | — | — | Fedora builds s390x only for the current release, and on a separate tree (`fedora-secondary`) — hence the single version there. -`opensuse` is openSUSE Tumbleweed, the only entry whose qpdf (12.3.2) already -clears the pikepdf threshold: the half-hour qpdf build never runs there, which -matters under s390x emulation. +`opensuse` covers two distinct products, not two versions of one. Leap `16.0` +is numbered and stable (SLE base) and is the default. `tumbleweed` is the +rolling one, kept as a bellwether for breakage to come: its snapshot drift is +real, and it demands a full `zypper dup` before anything can be installed. + +Both ship a qpdf above the pikepdf threshold, so the half-hour qpdf build +never runs there — which matters under s390x emulation. Provide an explicit image path as a positional argument to override the automatic download location. diff --git a/script/qemu/deploy_qemu.py b/script/qemu/deploy_qemu.py index c9da563..66e596d 100755 --- a/script/qemu/deploy_qemu.py +++ b/script/qemu/deploy_qemu.py @@ -113,10 +113,23 @@ ROCKY_VERSIONS: dict[str, tuple[str, str, int, str]] = { "9": ("9", "rocky9", 2048, "20G"), "10": ("10", "rocky10", 2048, "20G"), } -# openSUSE Tumbleweed : rolling, donc une seule « version ». C'est la seule -# distribution du catalogue dont qpdf (12.3.2) dépasse déjà le seuil de -# pikepdf 10 — aucune compilation de qpdf, ce qui change tout sous émulation. +# openSUSE, deux produits distincts et pas deux versions du même. +# Leap NUMÉROTÉ, base SLE, ~2 ans de support. C'est le défaut, et le +# seul des deux à proposer pour une installation qui doit durer. +# Tumbleweed ROLLING, sans numéro. Gardé comme banc d'essai des ruptures à +# venir, pas comme cible. Sa dérive d'instantanés est réelle : deux +# VM déployées le même jour ont vu git-daemon 2.54 sur s390x et +# 2.55 sur amd64, et l'image livrée est toujours en retard sur les +# dépôts, d'où le « zypper dup » obligatoire avant toute install. +# +# Les deux dépassent le seuil qpdf de pikepdf : aucune compilation de qpdf, ce +# qui change tout sous émulation s390x. +# +# osinfo : « opensuse16.0 » n'est pas encore dans osinfo-db, qui s'arrête à +# 15.6. osinfo_arg() replie sur le DERNIER id connu de la table — d'où l'ordre, +# Tumbleweed en second servant de repli à Leap. OPENSUSE_VERSIONS: dict[str, tuple[str, str, int, str]] = { + "16.0": ("16.0", "opensuse16.0", 2048, "20G"), "tumbleweed": ("tumbleweed", "opensusetumbleweed", 2048, "20G"), } # Arch est en rolling release : une seule « version » (latest). @@ -131,7 +144,7 @@ DISTROS: dict[str, tuple[dict[str, tuple[str, str, int, str]], str]] = { "fedora": (FEDORA_VERSIONS, "42"), "almalinux": (ALMALINUX_VERSIONS, "9"), "rocky": (ROCKY_VERSIONS, "10"), - "opensuse": (OPENSUSE_VERSIONS, "tumbleweed"), + "opensuse": (OPENSUSE_VERSIONS, "16.0"), "arch": (ARCH_VERSIONS, "latest"), } @@ -304,16 +317,25 @@ def image_candidates( f"Rocky-{version}-GenericCloud.latest.{a}.qcow2" ] if distro == "opensuse": - # Les architectures secondaires vivent sous /ports/, et zsystems DOUBLE - # l'architecture dans le nom du fichier — irrégularité vérifiée dans - # l'index, pas déduite : « .s390x-s390x-Cloud » contre « .x86_64-Cloud ». - port = {"s390x": "ports/zsystems/", "arm64": "ports/aarch64/"}.get( - arch, "" - ) + # zsystems DOUBLE l'architecture dans le nom du fichier — irrégularité + # vérifiée dans l'index, pas déduite : « .s390x-s390x-Cloud » contre + # « .x86_64-Cloud ». Elle vaut pour les DEUX produits. tag = f"{a}-{a}" if arch == "s390x" else a + if version == "tumbleweed": + # Tumbleweed sépare les architectures secondaires sous /ports/. + port = {"s390x": "ports/zsystems/", "arm64": "ports/aarch64/"}.get( + arch, "" + ) + return [ + f"{OPENSUSE_BASE}/{port}tumbleweed/appliances/" + f"openSUSE-Tumbleweed-Minimal-VM.{tag}-Cloud.qcow2" + ] + # Leap, lui, publie TOUTES les architectures dans un seul répertoire : + # les chemins /ports/ équivalents rendent 404. x86_64, aarch64 et s390x + # y sont côte à côte (relevé dans l'index de 16.0, les trois en 200). return [ - f"{OPENSUSE_BASE}/{port}tumbleweed/appliances/" - f"openSUSE-Tumbleweed-Minimal-VM.{tag}-Cloud.qcow2" + f"{OPENSUSE_BASE}/distribution/leap/{version}/appliances/" + f"Leap-{version}-Minimal-VM.{tag}-Cloud.qcow2" ] if distro == "arch": # Rolling release : image « latest » officielle (cloud-init inclus). @@ -375,7 +397,9 @@ def default_image_name(distro: str, code: str, arch: str, version: str) -> str: if distro == "arch": return f"arch-linux-{a}-cloudimg.qcow2" if distro == "opensuse": - return f"opensuse-tumbleweed-minimal-vm-{a}.qcow2" + if version == "tumbleweed": + return f"opensuse-tumbleweed-minimal-vm-{a}.qcow2" + return f"opensuse-leap-{version}-minimal-vm-{a}.qcow2" if distro in ("almalinux", "rocky"): # « latest » est MUTABLE : le nom de cache porte donc la majeure, et # une image déjà téléchargée sera réutilisée telle quelle. C'est voulu diff --git a/script/todo/todo.py b/script/todo/todo.py index 0c8039a..278915d 100755 --- a/script/todo/todo.py +++ b/script/todo/todo.py @@ -1027,7 +1027,10 @@ class TODO: "fedora": (["41", "42", "43", "44"], "42"), "almalinux": (["9", "10"], "9"), "rocky": (["9", "10"], "10"), - "opensuse": (["tumbleweed"], "tumbleweed"), + # Leap 16.0 par défaut : numérotée et stable. Tumbleweed reste offerte, + # comme banc d'essai des ruptures à venir. Voir OPENSUSE_VERSIONS dans + # deploy_qemu.py, qui fait autorité sur le catalogue. + "opensuse": (["16.0", "tumbleweed"], "16.0"), "arch": (["latest"], "latest"), } @@ -4510,9 +4513,14 @@ class TODO: def _qemu_zypper_mirror_cmd(self): """Réécrit l'hôte des dépôts zypper vers un miroir plus proche.""" mirrors = " ".join(self._QEMU_ZYPPER_MIRRORS) + # Leap et Tumbleweed n'ont pas le même arbre de dépôts : la rolling + # isole les architectures secondaires sous /ports/, Leap 16 unifie tout + # et garde s390x dans l'arbre principal (les /ports/ y rendent 404). return ( - "zp=tumbleweed; " - '[ "$(uname -m)" = s390x ] && zp=ports/zsystems/tumbleweed; ' + ". /etc/os-release; " + 'case "$ID" in *tumbleweed*) zp=tumbleweed; ' + '[ "$(uname -m)" = s390x ] && zp=ports/zsystems/tumbleweed;; ' + '*) zp="distribution/leap/$VERSION_ID";; esac; ' f"for zm in {mirrors}; do " "if curl -fsS --max-time 20 -o /dev/null " '"$zm/$zp/repo/oss/repodata/repomd.xml"; then ' @@ -4722,8 +4730,19 @@ class TODO: # celui de l'image. zypper proposait alors trois solutions et # attendait un choix ; « --non-interactive » prend le défaut, # « c » = annuler, et l'installation s'arrêtait là. + # + # Sur Leap, « dup » sert à CHANGER de version : l'y appeler irait + # contre la raison même de la choisir. « up » y suffit, l'image et + # ses dépôts portant la même version. + # $ID est déjà posé par le bloc miroir juste au-dessus ; on le + # relit quand même, pour ne pas dépendre de l'ordre de deux + # méthodes qui s'ignorent. + ". /etc/os-release; " + 'case "$ID" in *tumbleweed*) ' "sudo zypper --non-interactive dup --auto-agree-with-licenses " - "--allow-vendor-change || true; " + "--allow-vendor-change || true;; " + "*) sudo zypper --non-interactive up " + "--auto-agree-with-licenses || true;; esac; " "sudo zypper --non-interactive install " "--auto-agree-with-licenses $PKGS; " "elif command -v yum >/dev/null 2>&1; then "