[IMP] script qemu: support arm64/aarch64 (+ archi native marquée d'un *)
Ajoute l'architecture arm64 (aarch64) au déploiement, en plus d'amd64 (x86_64) et s390x. Disponibilité réelle vérifiée (juillet 2026) : - arm64 : Ubuntu, Debian, Fedora (Arch : pas d'image cloud aarch64 -> rejet). - s390x : Ubuntu seulement (inchangé). deploy_qemu.py : - host_arch() : arch native de l'hôte ; toute arch différente est ÉMULÉE (TCG, --virt-type qemu) — plus de liste FOREIGN_ARCHES figée. - virt_install : arm64 -> --arch aarch64 --machine virt --boot uefi (firmware AAVMF résolu par libvirt) ; s390x inchangé ; x86 UEFI/OVMF inchangé. - ensure_emulator(arch) généralisé : installe qemu-system-aarch64 + firmware UEFI AAVMF (arm64) ou qemu-system-s390x (s390x), selon le gestionnaire de paquets, avec vérif de présence (binaire + firmware pour arm64). - Validation --arch tôt via ARCH_DISTRO_SUPPORT (message clair si la distro ne publie pas l'arch). Les URLs d'images arm64 marchent déjà via les alias (fedora/arch aarch64 ; ubuntu/debian arm64). todo.py : menus d'architecture (VM unique + infra) proposent amd64/arm64/ s390x selon la distro ; l'architecture NATIVE de l'hôte est marquée d'un * (défaut) ; les autres sont signalées « émulé, lent ». Le catalogue infra est restreint aux distros publiant l'arch choisie (arm64 -> ubuntu/debian/fedora, s390x -> ubuntu). install_debian_dependency.sh : wkhtmltopdf (deb amd64 en dur) ignoré best-effort sur toute arch non-x86_64 (au lieu d'avorter l'install). Validé : dry-runs Ubuntu/Debian/Fedora arm64 (bonnes URLs + virt-install aarch64/virt/uefi/qemu), rejet Arch arm64, non-régression s390x, menus et filtrage simulés (natif *, arm64 par distro). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
8652c30507
commit
88dc1d5409
4 changed files with 231 additions and 122 deletions
|
|
@ -187,10 +187,11 @@ fi
|
||||||
#--------------------------------------------------
|
#--------------------------------------------------
|
||||||
# Install Wkhtmltopdf if needed
|
# Install Wkhtmltopdf if needed
|
||||||
#--------------------------------------------------
|
#--------------------------------------------------
|
||||||
if [ "$(uname -m)" = "s390x" ]; then
|
if [ "$(uname -m)" != "x86_64" ]; then
|
||||||
# wkhtmltopdf ne publie pas de build s390x (WKHTMLTOX_X64 est de l'amd64).
|
# WKHTMLTOX_X64 pointe vers un .deb amd64 : sur toute autre architecture
|
||||||
# On saute proprement plutôt que d'avorter tout l'install.
|
# (s390x, arm64/aarch64…) gdebi échouerait. On saute proprement plutôt que
|
||||||
echo "wkhtmltopdf : pas de build s390x, ignoré (optionnel)."
|
# d'avorter tout l'install (wkhtmltopdf est optionnel).
|
||||||
|
echo "wkhtmltopdf : pas de build pour $(uname -m), ignoré (optionnel)."
|
||||||
elif [ ${EL_INSTALL_WKHTMLTOPDF} = "True" ]; then
|
elif [ ${EL_INSTALL_WKHTMLTOPDF} = "True" ]; then
|
||||||
echo -e "\n---- Installing wkhtml ----"
|
echo -e "\n---- Installing wkhtml ----"
|
||||||
INSTALLED=$(dpkg -s wkhtmltox | grep installed)
|
INSTALLED=$(dpkg -s wkhtmltox | grep installed)
|
||||||
|
|
|
||||||
|
|
@ -110,15 +110,37 @@ ARCH_ALIASES: dict[str, dict[str, str]] = {
|
||||||
"arch": {"amd64": "x86_64", "arm64": "aarch64"},
|
"arch": {"amd64": "x86_64", "arm64": "aarch64"},
|
||||||
}
|
}
|
||||||
|
|
||||||
# Architectures « étrangères » à un hôte x86 : émulées en TCG (pas de KVM),
|
# Architectures non-x86 nécessitant une machine/un amorçage spécifiques (voir
|
||||||
# donc LENTES, avec une machine et un amorçage spécifiques (voir virt_install).
|
# virt_install). Émulées en TCG (pas de KVM), donc LENTES, quand elles
|
||||||
FOREIGN_ARCHES: tuple[str, ...] = ("s390x",)
|
# diffèrent de l'architecture de l'hôte.
|
||||||
|
NON_X86_ARCHES: tuple[str, ...] = ("arm64", "s390x")
|
||||||
|
|
||||||
# Distros publiant des images cloud s390x (IBM Z). Seul Ubuntu en publie :
|
# Distros publiant des images cloud par architecture (vérifié juillet 2026) :
|
||||||
# Debian et Fedora n'ont pas de qcow2 cloud s390x ; Arch ne cible que
|
# - s390x (IBM Z) : Ubuntu seulement (Debian/Fedora : 404 ; Arch : x86/arm).
|
||||||
# x86_64/aarch64. Vérifié en juillet 2026 (cloud-images.ubuntu.com : OK ;
|
# - arm64/aarch64 : Ubuntu, Debian, Fedora (Arch : pas d'image cloud officielle
|
||||||
# cloud.debian.org & fedora-secondary : 404).
|
# aarch64 sur geo.mirror.pkgbuild.com).
|
||||||
S390X_DISTROS: tuple[str, ...] = ("ubuntu",)
|
S390X_DISTROS: tuple[str, ...] = ("ubuntu",)
|
||||||
|
ARM64_DISTROS: tuple[str, ...] = ("ubuntu", "debian", "fedora")
|
||||||
|
# arch générique -> distros la publiant (pour valider --arch tôt).
|
||||||
|
ARCH_DISTRO_SUPPORT: dict[str, tuple[str, ...]] = {
|
||||||
|
"s390x": S390X_DISTROS,
|
||||||
|
"arm64": ARM64_DISTROS,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def host_arch() -> str:
|
||||||
|
"""Architecture de l'hôte en jeton générique (amd64/arm64/s390x)."""
|
||||||
|
try:
|
||||||
|
machine = os.uname().machine
|
||||||
|
except (AttributeError, OSError):
|
||||||
|
machine = ""
|
||||||
|
return {
|
||||||
|
"x86_64": "amd64",
|
||||||
|
"amd64": "amd64",
|
||||||
|
"aarch64": "arm64",
|
||||||
|
"arm64": "arm64",
|
||||||
|
"s390x": "s390x",
|
||||||
|
}.get(machine, "amd64")
|
||||||
|
|
||||||
ARCH_CLOUD_BASE = "https://geo.mirror.pkgbuild.com/images/latest"
|
ARCH_CLOUD_BASE = "https://geo.mirror.pkgbuild.com/images/latest"
|
||||||
|
|
||||||
|
|
@ -399,18 +421,44 @@ DAEMON_PACKAGES: dict[str, list[str]] = {
|
||||||
"brew": [],
|
"brew": [],
|
||||||
}
|
}
|
||||||
|
|
||||||
# Émulateur QEMU système s390x (IBM Z). Requis UNIQUEMENT pour --arch s390x sur
|
# Émulateurs QEMU système pour architectures non-x86, requis pour --arch
|
||||||
# un hôte non-s390x : virt-install a besoin du binaire qemu-system-s390x. NB :
|
# <arch> sur un hôte d'architecture différente (émulation TCG). Par arch puis
|
||||||
# sur apt, qemu-system-misc ne contient PAS s390x (alpha/avr/… seulement) —
|
# par gestionnaire de paquets. NB apt : qemu-system-misc ne contient PAS s390x
|
||||||
# c'est le paquet dédié qemu-system-s390x qui le fournit.
|
# (alpha/avr/… seulement) -> paquet dédié qemu-system-s390x ; qemu-system-arm
|
||||||
S390X_EMULATOR_PACKAGES: dict[str, list[str]] = {
|
# fournit qemu-system-aarch64 ; l'arm64 exige aussi le firmware UEFI AAVMF.
|
||||||
"apt": ["qemu-system-s390x"],
|
EMULATOR_PACKAGES: dict[str, dict[str, list[str]]] = {
|
||||||
"dnf": ["qemu-system-s390x"],
|
"s390x": {
|
||||||
"pacman": ["qemu-emulators-full"],
|
"apt": ["qemu-system-s390x"],
|
||||||
"zypper": ["qemu-s390"],
|
"dnf": ["qemu-system-s390x"],
|
||||||
"brew": [],
|
"pacman": ["qemu-emulators-full"],
|
||||||
|
"zypper": ["qemu-s390"],
|
||||||
|
"brew": [],
|
||||||
|
},
|
||||||
|
"arm64": {
|
||||||
|
"apt": ["qemu-system-arm", "qemu-efi-aarch64"],
|
||||||
|
"dnf": ["qemu-system-aarch64", "edk2-aarch64"],
|
||||||
|
"pacman": ["qemu-emulators-full", "edk2-aarch64"],
|
||||||
|
"zypper": ["qemu-arm", "qemu-uefi-aarch64"],
|
||||||
|
"brew": [],
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Binaire émulateur par arch (détection de présence).
|
||||||
|
EMULATOR_BINARY: dict[str, str] = {
|
||||||
|
"s390x": "qemu-system-s390x",
|
||||||
|
"arm64": "qemu-system-aarch64",
|
||||||
|
}
|
||||||
|
|
||||||
|
# Firmwares UEFI AAVMF possibles (arm64) : au moins un doit exister.
|
||||||
|
AARCH64_FIRMWARE_PATHS: tuple[str, ...] = (
|
||||||
|
"/usr/share/AAVMF/AAVMF_CODE.fd",
|
||||||
|
"/usr/share/AAVMF/AAVMF_CODE.no-secboot.fd",
|
||||||
|
"/usr/share/edk2/aarch64/QEMU_EFI.fd",
|
||||||
|
"/usr/share/edk2/aarch64/QEMU_EFI-silent.fd",
|
||||||
|
"/usr/share/qemu-efi-aarch64/QEMU_EFI.fd",
|
||||||
|
"/usr/share/edk2-armvirt/aarch64/QEMU_EFI.fd",
|
||||||
|
)
|
||||||
|
|
||||||
# Gestionnaires de paquets, dans l'ordre de préférence :
|
# Gestionnaires de paquets, dans l'ordre de préférence :
|
||||||
# (clé TOOL_PACKAGES, binaire à détecter, commande d'installation, sudo, refresh)
|
# (clé TOOL_PACKAGES, binaire à détecter, commande d'installation, sudo, refresh)
|
||||||
PKG_MANAGERS: tuple[
|
PKG_MANAGERS: tuple[
|
||||||
|
|
@ -619,31 +667,43 @@ def ensure_tools(runner: Runner, assume_yes: bool, no_install: bool) -> None:
|
||||||
ensure_libvirt_service(runner)
|
ensure_libvirt_service(runner)
|
||||||
|
|
||||||
|
|
||||||
def ensure_s390x_emulator(
|
def emulator_ready(arch: str) -> bool:
|
||||||
runner: Runner, assume_yes: bool, no_install: bool
|
"""Vrai si l'émulateur (et, pour arm64, un firmware UEFI AAVMF) est là."""
|
||||||
|
if shutil.which(EMULATOR_BINARY[arch]) is None:
|
||||||
|
return False
|
||||||
|
if arch == "arm64":
|
||||||
|
return any(os.path.exists(p) for p in AARCH64_FIRMWARE_PATHS)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def ensure_emulator(
|
||||||
|
arch: str, runner: Runner, assume_yes: bool, no_install: bool
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Vérifie que qemu-system-s390x est présent (requis pour --arch s390x sur
|
"""Vérifie l'émulateur QEMU système pour `arch` (et le firmware UEFI pour
|
||||||
un hôte x86) ; l'installe au besoin via le gestionnaire de paquets."""
|
arm64), requis quand on émule une architecture différente de l'hôte ;
|
||||||
if shutil.which("qemu-system-s390x"):
|
l'installe au besoin via le gestionnaire de paquets."""
|
||||||
|
binary = EMULATOR_BINARY[arch]
|
||||||
|
if emulator_ready(arch):
|
||||||
return
|
return
|
||||||
pm = detect_pkg_manager()
|
pm = detect_pkg_manager()
|
||||||
if pm is None:
|
if pm is None:
|
||||||
sys.exit(
|
sys.exit(
|
||||||
" Émulateur s390x introuvable (qemu-system-s390x) et gestionnaire "
|
f" Émulateur {arch} introuvable ({binary}) et gestionnaire de "
|
||||||
"de paquets non reconnu.\n Installez-le manuellement."
|
"paquets non reconnu.\n Installez-le manuellement."
|
||||||
)
|
)
|
||||||
pm_key, install_cmd, use_sudo, refresh = pm
|
pm_key, install_cmd, use_sudo, refresh = pm
|
||||||
packages = S390X_EMULATOR_PACKAGES.get(pm_key, [])
|
packages = EMULATOR_PACKAGES.get(arch, {}).get(pm_key, [])
|
||||||
if not packages:
|
if not packages:
|
||||||
sys.exit(
|
sys.exit(
|
||||||
" Émulateur s390x introuvable (qemu-system-s390x) : installez le "
|
f" Émulateur {arch} introuvable ({binary}) : installez le paquet "
|
||||||
"paquet QEMU système s390x de votre distribution."
|
"QEMU système correspondant de votre distribution "
|
||||||
|
"(+ firmware UEFI pour arm64)."
|
||||||
)
|
)
|
||||||
full_cmd = install_cmd + packages
|
full_cmd = install_cmd + packages
|
||||||
printable = ("sudo " if use_sudo and runner.use_sudo else "") + " ".join(
|
printable = ("sudo " if use_sudo and runner.use_sudo else "") + " ".join(
|
||||||
full_cmd
|
full_cmd
|
||||||
)
|
)
|
||||||
print(" Émulateur s390x manquant (qemu-system-s390x).")
|
print(f" Émulateur {arch} manquant ({binary}).")
|
||||||
print(f" Commande d'installation : {printable}")
|
print(f" Commande d'installation : {printable}")
|
||||||
if no_install:
|
if no_install:
|
||||||
sys.exit(
|
sys.exit(
|
||||||
|
|
@ -651,18 +711,18 @@ def ensure_s390x_emulator(
|
||||||
" Installez manuellement : " + printable
|
" Installez manuellement : " + printable
|
||||||
)
|
)
|
||||||
if not assume_yes and not prompt_yes_no(
|
if not assume_yes and not prompt_yes_no(
|
||||||
" Installer l'émulateur s390x maintenant ?"
|
f" Installer l'émulateur {arch} maintenant ?"
|
||||||
):
|
):
|
||||||
sys.exit(" Installation refusée.\n Commande manuelle : " + printable)
|
sys.exit(" Installation refusée.\n Commande manuelle : " + printable)
|
||||||
if refresh:
|
if refresh:
|
||||||
runner.run(refresh, privileged=use_sudo, check=False)
|
runner.run(refresh, privileged=use_sudo, check=False)
|
||||||
runner.run(full_cmd, privileged=use_sudo)
|
runner.run(full_cmd, privileged=use_sudo)
|
||||||
if not shutil.which("qemu-system-s390x"):
|
if not emulator_ready(arch):
|
||||||
sys.exit(
|
sys.exit(
|
||||||
" qemu-system-s390x toujours absent après installation.\n"
|
f" Émulateur {arch} ({binary}) ou firmware toujours absent après "
|
||||||
f" Essayez manuellement : {printable}"
|
f"installation.\n Essayez manuellement : {printable}"
|
||||||
)
|
)
|
||||||
print(" Émulateur s390x installé avec succès.")
|
print(f" Émulateur {arch} installé avec succès.")
|
||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------------- #
|
# --------------------------------------------------------------------------- #
|
||||||
|
|
@ -1046,10 +1106,11 @@ def virt_install(
|
||||||
osinfo: str,
|
osinfo: str,
|
||||||
runner: Runner,
|
runner: Runner,
|
||||||
) -> None:
|
) -> None:
|
||||||
foreign = args.arch in FOREIGN_ARCHES
|
# Émulée (TCG, pas de KVM) si l'arch demandée diffère de celle de l'hôte.
|
||||||
|
emulated = args.arch != host_arch()
|
||||||
# s390x n'a pas de port série ISA : la console est SCLP (ttysclp0), et non
|
# s390x n'a pas de port série ISA : la console est SCLP (ttysclp0), et non
|
||||||
# ttyS0. Ailleurs (x86), console série classique.
|
# ttyS0. Ailleurs (x86/arm64), console série classique.
|
||||||
console_target = "sclp" if foreign else "serial"
|
console_target = "sclp" if args.arch == "s390x" else "serial"
|
||||||
cmd = [
|
cmd = [
|
||||||
"virt-install",
|
"virt-install",
|
||||||
"--name",
|
"--name",
|
||||||
|
|
@ -1078,20 +1139,17 @@ def virt_install(
|
||||||
"--console",
|
"--console",
|
||||||
f"pty,target_type={console_target}",
|
f"pty,target_type={console_target}",
|
||||||
]
|
]
|
||||||
if foreign:
|
if args.arch == "s390x":
|
||||||
# s390x (IBM Z) sur hôte x86 : émulation TCG (--virt-type qemu, pas de
|
# s390x (IBM Z) : machine s390-ccw-virtio, amorçage IPL/zipl depuis le
|
||||||
# KVM), machine s390-ccw-virtio, amorçage IPL/zipl depuis le disque
|
# disque (ni BIOS ni UEFI/OVMF -> aucun --boot).
|
||||||
# (ni BIOS ni UEFI/OVMF -> aucun --boot). LENT (émulation logicielle).
|
cmd += ["--arch", "s390x", "--machine", "s390-ccw-virtio"]
|
||||||
cmd += [
|
elif args.arch == "arm64":
|
||||||
"--arch",
|
# arm64/aarch64 : machine « virt » + UEFI (firmware AAVMF résolu par
|
||||||
"s390x",
|
# libvirt d'après --arch aarch64). Les images cloud arm64 n'ont pas de
|
||||||
"--machine",
|
# BIOS -> UEFI obligatoire.
|
||||||
"s390-ccw-virtio",
|
cmd += ["--arch", "aarch64", "--machine", "virt", "--boot", "uefi"]
|
||||||
"--virt-type",
|
|
||||||
"qemu",
|
|
||||||
]
|
|
||||||
elif not args.bios:
|
elif not args.bios:
|
||||||
# Boot UEFI par défaut : Debian 13 (trixie) et les images cloud
|
# Boot UEFI par défaut (x86) : Debian 13 (trixie) et les images cloud
|
||||||
# récentes n'embarquent plus le chargeur BIOS/GRUB-pc et partent en
|
# récentes n'embarquent plus le chargeur BIOS/GRUB-pc et partent en
|
||||||
# boucle « Booting... » en SeaBIOS. UEFI (OVMF) fonctionne pour
|
# boucle « Booting... » en SeaBIOS. UEFI (OVMF) fonctionne pour
|
||||||
# Ubuntu/Debian/Fedora. --bios force l'ancien BIOS si OVMF est absent.
|
# Ubuntu/Debian/Fedora. --bios force l'ancien BIOS si OVMF est absent.
|
||||||
|
|
@ -1103,6 +1161,10 @@ def virt_install(
|
||||||
"uefi,firmware.feature0.name=secure-boot,"
|
"uefi,firmware.feature0.name=secure-boot,"
|
||||||
"firmware.feature0.enabled=no",
|
"firmware.feature0.enabled=no",
|
||||||
]
|
]
|
||||||
|
if emulated:
|
||||||
|
# Architecture différente de l'hôte -> émulation logicielle TCG
|
||||||
|
# (pas de KVM). LENT.
|
||||||
|
cmd += ["--virt-type", "qemu"]
|
||||||
if not args.attach_console:
|
if not args.attach_console:
|
||||||
cmd.append("--noautoconsole")
|
cmd.append("--noautoconsole")
|
||||||
runner.run(cmd, privileged=True)
|
runner.run(cmd, privileged=True)
|
||||||
|
|
@ -1183,8 +1245,9 @@ def build_parser() -> argparse.ArgumentParser:
|
||||||
g_img.add_argument(
|
g_img.add_argument(
|
||||||
"--arch",
|
"--arch",
|
||||||
default="amd64",
|
default="amd64",
|
||||||
help="Architecture de l'image (défaut : amd64). s390x (IBM Z) n'est "
|
help="Architecture de l'image (défaut : amd64). amd64/x86_64, "
|
||||||
"disponible que pour Ubuntu et est ÉMULÉ (lent) sur un hôte x86.",
|
"arm64/aarch64 (Ubuntu/Debian/Fedora) ou s390x (Ubuntu). Toute arch "
|
||||||
|
"différente de l'hôte est ÉMULÉE (TCG, lente).",
|
||||||
)
|
)
|
||||||
g_img.add_argument(
|
g_img.add_argument(
|
||||||
"--image-dir",
|
"--image-dir",
|
||||||
|
|
@ -1420,13 +1483,13 @@ def main() -> None:
|
||||||
f"Version {args.version!r} inconnue pour {args.distro}. "
|
f"Version {args.version!r} inconnue pour {args.distro}. "
|
||||||
f"Choix : {', '.join(versions)} (voir --list-images)."
|
f"Choix : {', '.join(versions)} (voir --list-images)."
|
||||||
)
|
)
|
||||||
# s390x n'est publié en image cloud que par Ubuntu (voir S390X_DISTROS).
|
# Certaines architectures ne sont publiées que par une partie des distros
|
||||||
if args.arch == "s390x" and args.distro not in S390X_DISTROS:
|
# (voir ARCH_DISTRO_SUPPORT) : on valide tôt plutôt qu'échouer au download.
|
||||||
|
supported = ARCH_DISTRO_SUPPORT.get(args.arch)
|
||||||
|
if supported is not None and args.distro not in supported:
|
||||||
sys.exit(
|
sys.exit(
|
||||||
f"Architecture s390x indisponible pour {args.distro!r} : seul "
|
f"Architecture {args.arch} indisponible pour {args.distro!r} : "
|
||||||
f"Ubuntu publie des images cloud s390x ({', '.join(S390X_DISTROS)})."
|
f"images cloud publiées seulement pour {', '.join(supported)}."
|
||||||
"\n Debian/Fedora n'en publient pas ; Arch ne cible que "
|
|
||||||
"x86_64/aarch64."
|
|
||||||
)
|
)
|
||||||
code, default_osinfo, min_ram, min_disk = versions[args.version]
|
code, default_osinfo, min_ram, min_disk = versions[args.version]
|
||||||
if args.codename:
|
if args.codename:
|
||||||
|
|
@ -1499,13 +1562,17 @@ def main() -> None:
|
||||||
|
|
||||||
if not args.dry_run:
|
if not args.dry_run:
|
||||||
ensure_tools(runner, args.assume_yes, args.no_install_deps)
|
ensure_tools(runner, args.assume_yes, args.no_install_deps)
|
||||||
if args.arch in FOREIGN_ARCHES:
|
# Émulation requise si l'arch diffère de l'hôte : installe l'émulateur
|
||||||
ensure_s390x_emulator(
|
# QEMU système adéquat (+ firmware UEFI pour arm64) et prévient de la
|
||||||
runner, args.assume_yes, args.no_install_deps
|
# lenteur.
|
||||||
|
if args.arch in EMULATOR_BINARY and args.arch != host_arch():
|
||||||
|
ensure_emulator(
|
||||||
|
args.arch, runner, args.assume_yes, args.no_install_deps
|
||||||
)
|
)
|
||||||
print(
|
print(
|
||||||
" Note : s390x est ÉMULÉ (TCG) sur cet hôte — le boot et "
|
f" Note : {args.arch} est ÉMULÉ (TCG) sur cet hôte "
|
||||||
"l'installation seront nettement plus lents que x86."
|
f"({host_arch()}) — le boot et l'installation seront "
|
||||||
|
"nettement plus lents que l'architecture native."
|
||||||
)
|
)
|
||||||
|
|
||||||
print(f"\n== 1/5 Image cloud ({args.distro} {args.version} / {code}) ==")
|
print(f"\n== 1/5 Image cloud ({args.distro} {args.version} / {code}) ==")
|
||||||
|
|
|
||||||
|
|
@ -854,31 +854,12 @@ class TODO:
|
||||||
print(f"{t('Invalid selection, using')} {default}")
|
print(f"{t('Invalid selection, using')} {default}")
|
||||||
return default
|
return default
|
||||||
|
|
||||||
# Distros publiant des images cloud s390x (IBM Z). Seul Ubuntu en publie
|
# Distros publiant des images cloud par architecture (cohérent avec
|
||||||
# (cohérent avec S390X_DISTROS de deploy_qemu.py).
|
# S390X_DISTROS / ARM64_DISTROS de deploy_qemu.py). amd64 : toutes.
|
||||||
_QEMU_S390X_DISTROS = ("ubuntu",)
|
_QEMU_S390X_DISTROS = ("ubuntu",)
|
||||||
|
_QEMU_ARM64_DISTROS = ("ubuntu", "debian", "fedora")
|
||||||
def _qemu_prompt_arch(self, distro):
|
# Alias distro pour l'affichage (jeton générique -> nom courant).
|
||||||
"""Demande l'architecture. s390x n'est proposé que pour les distros qui
|
_QEMU_ARCH_ALIAS = {"amd64": "x86_64", "arm64": "aarch64"}
|
||||||
publient des images s390x (Ubuntu) ; il est ÉMULÉ (lent) sur x86."""
|
|
||||||
if distro not in self._QEMU_S390X_DISTROS:
|
|
||||||
return "amd64"
|
|
||||||
print(f"\n{t('Architecture:')}")
|
|
||||||
print(f" [1] amd64 *")
|
|
||||||
print(f" [2] s390x ({t('IBM Z — emulated, slow on x86')})")
|
|
||||||
sel = (
|
|
||||||
input(f"{t('Choice (number or name, blank = amd64):')} ")
|
|
||||||
.strip()
|
|
||||||
.lower()
|
|
||||||
)
|
|
||||||
if sel in ("2", "s390x"):
|
|
||||||
warn = t(
|
|
||||||
"s390x is emulated (TCG): boot and install are much "
|
|
||||||
"slower than x86."
|
|
||||||
)
|
|
||||||
print(f"⚠ {warn}")
|
|
||||||
return "s390x"
|
|
||||||
return "amd64"
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _native_arch():
|
def _native_arch():
|
||||||
|
|
@ -896,39 +877,74 @@ class TODO:
|
||||||
"s390x": "s390x",
|
"s390x": "s390x",
|
||||||
}.get(machine, "amd64")
|
}.get(machine, "amd64")
|
||||||
|
|
||||||
def _qemu_prompt_infra_arch(self):
|
def _qemu_arch_distros(self, arch):
|
||||||
"""Demande l'architecture du parc (défaut : native de l'hôte). s390x
|
"""Distros supportant `arch` (None = toutes, cas amd64)."""
|
||||||
est proposé mais ÉMULÉ (lent) et limité à Ubuntu (seule distro avec
|
if arch == "s390x":
|
||||||
des images cloud s390x)."""
|
return self._QEMU_S390X_DISTROS
|
||||||
native = self._native_arch()
|
if arch == "arm64":
|
||||||
opts = [native]
|
return self._QEMU_ARM64_DISTROS
|
||||||
if native != "s390x":
|
return None
|
||||||
opts.append("s390x") # émulé, disponible en plus du natif
|
|
||||||
|
def _qemu_ask_arch(self, opts, native):
|
||||||
|
"""Affiche les architectures `opts` (natif marqué d'un *) et renvoie le
|
||||||
|
choix. Toute arch non native est ÉMULÉE (TCG, lente)."""
|
||||||
print(f"\n{t('Architecture:')}")
|
print(f"\n{t('Architecture:')}")
|
||||||
for i, a in enumerate(opts, 1):
|
for i, a in enumerate(opts, 1):
|
||||||
tag = f" ({t('native')}) *" if a == native else ""
|
alias = self._QEMU_ARCH_ALIAS.get(a)
|
||||||
extra = ""
|
label = f"{a} ({alias})" if alias else a
|
||||||
if a == "s390x":
|
if a == native:
|
||||||
extra = f" ({t('IBM Z — emulated, slow on x86; Ubuntu only')})"
|
label += f" — {t('native')} *"
|
||||||
print(f" [{i}] {a}{tag}{extra}")
|
elif a == "s390x":
|
||||||
|
label += f" ({t('IBM Z — emulated, slow; Ubuntu only')})"
|
||||||
|
elif a == "arm64":
|
||||||
|
label += f" ({t('ARM 64-bit — emulated, slow')})"
|
||||||
|
else:
|
||||||
|
label += f" ({t('emulated, slow')})"
|
||||||
|
print(f" [{i}] {label}")
|
||||||
sel = (
|
sel = (
|
||||||
input(f"{t('Choice (number or name, blank = native):')} ")
|
input(f"{t('Choice (number or name, blank = native):')} ")
|
||||||
.strip()
|
.strip()
|
||||||
.lower()
|
.lower()
|
||||||
)
|
)
|
||||||
if not sel:
|
chosen = native
|
||||||
return native
|
if sel:
|
||||||
for i, a in enumerate(opts, 1):
|
chosen = None
|
||||||
if sel == str(i) or sel == a:
|
for i, a in enumerate(opts, 1):
|
||||||
if a == "s390x":
|
if sel in (str(i), a, self._QEMU_ARCH_ALIAS.get(a)):
|
||||||
warn = t(
|
chosen = a
|
||||||
"s390x is emulated (TCG): boot and install are much "
|
break
|
||||||
"slower than x86."
|
if chosen is None:
|
||||||
)
|
print(f"{t('Invalid selection, using')} {native}")
|
||||||
print(f"⚠ {warn}")
|
chosen = native
|
||||||
return a
|
if chosen != native:
|
||||||
print(f"{t('Invalid selection, using')} {native}")
|
warn = t(
|
||||||
return native
|
"This architecture is emulated (TCG): boot and install are"
|
||||||
|
" much slower than the native one."
|
||||||
|
)
|
||||||
|
print(f"⚠ {warn}")
|
||||||
|
return chosen
|
||||||
|
|
||||||
|
def _qemu_prompt_arch(self, distro):
|
||||||
|
"""Architecture pour un déploiement de VM unique. Propose amd64, plus
|
||||||
|
arm64/s390x si la distro choisie publie ces images."""
|
||||||
|
opts = ["amd64"]
|
||||||
|
if distro in self._QEMU_ARM64_DISTROS:
|
||||||
|
opts.append("arm64")
|
||||||
|
if distro in self._QEMU_S390X_DISTROS:
|
||||||
|
opts.append("s390x")
|
||||||
|
if len(opts) == 1:
|
||||||
|
return "amd64" # rien à demander
|
||||||
|
return self._qemu_ask_arch(opts, self._native_arch())
|
||||||
|
|
||||||
|
def _qemu_prompt_infra_arch(self):
|
||||||
|
"""Architecture du parc (défaut : native de l'hôte, marquée d'un *).
|
||||||
|
Toute arch non native est émulée ; le catalogue est ensuite restreint
|
||||||
|
aux distros publiant cette arch."""
|
||||||
|
native = self._native_arch()
|
||||||
|
opts = ["amd64", "arm64", "s390x"]
|
||||||
|
if native not in opts: # hôte exotique : garder le natif en tête
|
||||||
|
opts.insert(0, native)
|
||||||
|
return self._qemu_ask_arch(opts, native)
|
||||||
|
|
||||||
def _qemu_list_images(self):
|
def _qemu_list_images(self):
|
||||||
"""Affiche la liste des distros/versions et leurs specs."""
|
"""Affiche la liste des distros/versions et leurs specs."""
|
||||||
|
|
@ -1913,16 +1929,18 @@ class TODO:
|
||||||
return
|
return
|
||||||
distros = list(mod.DISTROS)
|
distros = list(mod.DISTROS)
|
||||||
|
|
||||||
# 0) Architecture du parc (défaut : native de l'hôte). s390x n'a des
|
# 0) Architecture du parc (défaut : native de l'hôte). arm64 et s390x
|
||||||
# images cloud que pour Ubuntu -> on restreint le catalogue.
|
# n'ont pas d'images pour toutes les distros -> on restreint le
|
||||||
|
# catalogue aux distros qui publient l'arch choisie.
|
||||||
arch = self._qemu_prompt_infra_arch()
|
arch = self._qemu_prompt_infra_arch()
|
||||||
if arch == "s390x":
|
allowed = self._qemu_arch_distros(arch)
|
||||||
keep = [d for d in distros if d in self._QEMU_S390X_DISTROS]
|
if allowed is not None:
|
||||||
|
keep = [d for d in distros if d in allowed]
|
||||||
dropped = [d for d in distros if d not in keep]
|
dropped = [d for d in distros if d not in keep]
|
||||||
if dropped:
|
if dropped:
|
||||||
print(
|
print(
|
||||||
f" ⚠ {t('s390x images only exist for:')} "
|
f" ⚠ {t('images for this arch only exist for:')} "
|
||||||
f"{', '.join(self._QEMU_S390X_DISTROS)} "
|
f"{', '.join(allowed)} "
|
||||||
f"({t('ignored:')} {', '.join(dropped)})"
|
f"({t('ignored:')} {', '.join(dropped)})"
|
||||||
)
|
)
|
||||||
distros = keep
|
distros = keep
|
||||||
|
|
|
||||||
|
|
@ -1174,6 +1174,29 @@ TRANSLATIONS = {
|
||||||
"fr": "IBM Z — émulé, lent sur x86 ; Ubuntu uniquement",
|
"fr": "IBM Z — émulé, lent sur x86 ; Ubuntu uniquement",
|
||||||
"en": "IBM Z — emulated, slow on x86; Ubuntu only",
|
"en": "IBM Z — emulated, slow on x86; Ubuntu only",
|
||||||
},
|
},
|
||||||
|
"IBM Z — emulated, slow; Ubuntu only": {
|
||||||
|
"fr": "IBM Z — émulé, lent ; Ubuntu uniquement",
|
||||||
|
"en": "IBM Z — emulated, slow; Ubuntu only",
|
||||||
|
},
|
||||||
|
"ARM 64-bit — emulated, slow": {
|
||||||
|
"fr": "ARM 64 bits — émulé, lent",
|
||||||
|
"en": "ARM 64-bit — emulated, slow",
|
||||||
|
},
|
||||||
|
"emulated, slow": {
|
||||||
|
"fr": "émulé, lent",
|
||||||
|
"en": "emulated, slow",
|
||||||
|
},
|
||||||
|
"This architecture is emulated (TCG): boot and install are"
|
||||||
|
" much slower than the native one.": {
|
||||||
|
"fr": "Cette architecture est émulée (TCG) : le boot et l'installation"
|
||||||
|
" sont bien plus lents que l'architecture native.",
|
||||||
|
"en": "This architecture is emulated (TCG): boot and install are"
|
||||||
|
" much slower than the native one.",
|
||||||
|
},
|
||||||
|
"images for this arch only exist for:": {
|
||||||
|
"fr": "images pour cette architecture disponibles seulement pour :",
|
||||||
|
"en": "images for this arch only exist for:",
|
||||||
|
},
|
||||||
"Choice (number or name, blank = native):": {
|
"Choice (number or name, blank = native):": {
|
||||||
"fr": "Choix (numéro ou nom, vide = native) :",
|
"fr": "Choix (numéro ou nom, vide = native) :",
|
||||||
"en": "Choice (number or name, blank = native):",
|
"en": "Choice (number or name, blank = native):",
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue