[ADD] qemu: openSUSE Leap 16.0, numbered, as the default

The catalogue only offered openSUSE Tumbleweed, a rolling release with
no version number. Nearly every openSUSE incident in this series came
from that: the cloud image is a snapshot lagging behind its own repos,
hence the mandatory "zypper dup", and two VMs deployed the same day saw
git-daemon 2.54 on s390x against 2.55 on amd64. For an ERP platform,
that is not what should be offered by default.

Leap 16.0 is numbered, stable, and publishes the three architectures
that matter -- verified, x86_64, aarch64 and s390x all 200. It also
unifies its tree: no separate /ports/, unlike Tumbleweed, whose
equivalent paths 404 for Leap.

Tumbleweed stays on offer, as a bellwether for breakage to come. Two
things separate them in the scripts: the repository path, and "dup" --
which on Leap means CHANGING version, not updating.

--- FR ---

Le catalogue n'offrait qu'openSUSE Tumbleweed, une rolling sans numéro
de version. Presque tous les incidents openSUSE de la série venaient de
là : l'image cloud est un instantané en retard sur ses dépôts, d'où le
« zypper dup » obligatoire, et deux VM déployées le même jour ont vu
git-daemon 2.54 sur s390x contre 2.55 sur amd64. Pour une plateforme
ERP, ce n'est pas ce qu'on veut proposer par défaut.

Leap 16.0 est numérotée, stable, et publie les trois architectures qui
comptent — vérifié, x86_64, aarch64 et s390x en 200. Elle unifie de plus
son arbre : pas de /ports/ séparé, contrairement à Tumbleweed, dont les
chemins équivalents rendent 404 pour Leap.

Tumbleweed reste offerte, comme banc d'essai des ruptures à venir.
Deux points les séparent dans les scripts : le chemin des dépôts, et
« dup » — qui sur Leap sert à CHANGER de version, pas à mettre à jour.

Assisted-by: Claude Opus 5
This commit is contained in:
Mathieu Benoit 2026-08-12 01:16:17 -04:00
parent e20d8d9baa
commit 9c470f065e
7 changed files with 116 additions and 39 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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