[IMP] script qemu: default VM sizing to per-version minimums

Replace the fixed 8192 MB / 4 vCPU / 20G defaults with the minimum
resources required by the chosen Ubuntu version (libosinfo/osinfo-db
values): 20.04 -> 2048 MB/5G, 22.04 -> 2048 MB/10G, 24.04+ -> 3072
MB/20G. --vcpus now defaults to 2. This stops a small host from being
starved by an oversized default (an 8 GB VM failed to allocate on a
6.7 GB host) and silences the libvirt "less than recommended" warning.

In the todo menu, leaving the RAM/vCPU/disk fields blank now means
"version minimum" (the flag is simply not passed) instead of forcing
8192/4/20G. Any explicit value still overrides. README regenerated.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Mathieu Benoit 2026-07-19 06:26:43 +00:00
parent 935919e07b
commit a202143c30
6 changed files with 69 additions and 42 deletions

View file

@ -205,7 +205,10 @@ parameters and builds the command for you.
- `--image-dir` — image cache directory (default `/var/lib/libvirt/images/iso`).
- `--download-only` — download the image then exit (no VM).
- `--name` — VM name (required for deployment).
- `--memory`, `--vcpus`, `--disk-size` — VM sizing.
- `--memory`, `--vcpus`, `--disk-size` — VM sizing. When omitted, `--memory`
and `--disk-size` default to the **minimum required by the chosen Ubuntu
version** (libosinfo values: 20.04 → 2048 MB/5G, 22.04 → 2048 MB/10G,
24.04+ → 3072 MB/20G); `--vcpus` defaults to 2.
- `--ssh-key`, `--ask-password`, `--password-hash` — authentication.
- `-y` / `--assume-yes` — auto-accept dependency installation.
- `--no-install-deps` — never auto-install dependencies.
@ -233,7 +236,10 @@ vous.
`/var/lib/libvirt/images/iso`).
- `--download-only` — télécharge l'image puis quitte (sans VM).
- `--name` — nom de la VM (requis pour le déploiement).
- `--memory`, `--vcpus`, `--disk-size` — dimensionnement de la VM.
- `--memory`, `--vcpus`, `--disk-size` — dimensionnement de la VM. Omis,
`--memory` et `--disk-size` prennent le **minimum requis par la version
Ubuntu** choisie (valeurs libosinfo : 20.04 → 2048 Mo/5G, 22.04 →
2048 Mo/10G, 24.04+ → 3072 Mo/20G) ; `--vcpus` vaut 2 par défaut.
- `--ssh-key`, `--ask-password`, `--password-hash` — authentification.
- `-y` / `--assume-yes` — accepte automatiquement l'installation des
dépendances.

View file

@ -120,7 +120,10 @@ vous.
`/var/lib/libvirt/images/iso`).
- `--download-only` — télécharge l'image puis quitte (sans VM).
- `--name` — nom de la VM (requis pour le déploiement).
- `--memory`, `--vcpus`, `--disk-size` — dimensionnement de la VM.
- `--memory`, `--vcpus`, `--disk-size` — dimensionnement de la VM. Omis,
`--memory` et `--disk-size` prennent le **minimum requis par la version
Ubuntu** choisie (valeurs libosinfo : 20.04 → 2048 Mo/5G, 22.04 →
2048 Mo/10G, 24.04+ → 3072 Mo/20G) ; `--vcpus` vaut 2 par défaut.
- `--ssh-key`, `--ask-password`, `--password-hash` — authentification.
- `-y` / `--assume-yes` — accepte automatiquement l'installation des
dépendances.

View file

@ -112,7 +112,10 @@ parameters and builds the command for you.
- `--image-dir` — image cache directory (default `/var/lib/libvirt/images/iso`).
- `--download-only` — download the image then exit (no VM).
- `--name` — VM name (required for deployment).
- `--memory`, `--vcpus`, `--disk-size` — VM sizing.
- `--memory`, `--vcpus`, `--disk-size` — VM sizing. When omitted, `--memory`
and `--disk-size` default to the **minimum required by the chosen Ubuntu
version** (libosinfo values: 20.04 → 2048 MB/5G, 22.04 → 2048 MB/10G,
24.04+ → 3072 MB/20G); `--vcpus` defaults to 2.
- `--ssh-key`, `--ask-password`, `--password-hash` — authentication.
- `-y` / `--assume-yes` — auto-accept dependency installation.
- `--no-install-deps` — never auto-install dependencies.

View file

@ -49,18 +49,22 @@ import urllib.request
from pathlib import Path
# --------------------------------------------------------------------------- #
# Table des versions Ubuntu -> (nom de code, valeur --osinfo/libosinfo)
# Le nom de code sert à construire l'URL de l'image cloud. Les valeurs LTS sont
# stables ; --codename et --osinfo permettent de surcharger si la table vieillit.
# Table des versions Ubuntu -> (nom de code, --osinfo, RAM min. Mo, disque min.)
# Le nom de code sert à construire l'URL de l'image cloud. La RAM et le disque
# minimaux proviennent de libosinfo (osinfo-db) : ce sont les seuils sous
# lesquels virt-install émet un avertissement. Ils servent de valeurs PAR
# DÉFAUT — une VM Ubuntu démarre avec ça sans gaspiller la RAM de l'hôte. Les
# valeurs LTS sont stables ; --codename et --osinfo surchargent si la table
# vieillit ; --memory / --disk-size surchargent le dimensionnement.
# --------------------------------------------------------------------------- #
UBUNTU_VERSIONS: dict[str, tuple[str, str]] = {
"20.04": ("focal", "ubuntu20.04"),
"22.04": ("jammy", "ubuntu22.04"),
"24.04": ("noble", "ubuntu24.04"),
"24.10": ("oracular", "ubuntu24.10"),
"25.04": ("plucky", "ubuntu25.04"),
"25.10": ("questing", "ubuntu25.10"),
# "26.04": ("resolute", "ubuntu26.04"),
UBUNTU_VERSIONS: dict[str, tuple[str, str, int, str]] = {
"20.04": ("focal", "ubuntu20.04", 2048, "5G"),
"22.04": ("jammy", "ubuntu22.04", 2048, "10G"),
"24.04": ("noble", "ubuntu24.04", 3072, "20G"),
"24.10": ("oracular", "ubuntu24.10", 3072, "20G"),
"25.04": ("plucky", "ubuntu25.04", 3072, "20G"),
"25.10": ("questing", "ubuntu25.10", 3072, "20G"),
# "26.04": ("resolute", "ubuntu26.04", 3072, "20G"),
}
CLOUD_IMG_BASE = "https://cloud-images.ubuntu.com"
@ -682,8 +686,9 @@ def ssh_command(user: str, ip: str, has_key: bool) -> str:
# --------------------------------------------------------------------------- #
def build_parser() -> argparse.ArgumentParser:
versions_help = "\n".join(
f" {v:<7} {code:<10} {image_url(code, 'amd64')}"
for v, (code, _osinfo) in UBUNTU_VERSIONS.items()
f" {v:<7} {code:<10} RAM≥{ram:<5}Mo disque≥{disk:<4} "
f"{image_url(code, 'amd64')}"
for v, (code, _osinfo, ram, disk) in UBUNTU_VERSIONS.items()
)
p = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter,
@ -739,15 +744,20 @@ def build_parser() -> argparse.ArgumentParser:
"--hostname", help="Nom d'hôte interne (défaut : --name)."
)
g_vm.add_argument(
"--memory", type=int, default=8192, help="RAM en Mo (défaut : 8192)."
"--memory",
type=int,
default=None,
help="RAM en Mo (défaut : minimum requis par la version Ubuntu, "
"voir la liste ci-dessous).",
)
g_vm.add_argument(
"--vcpus", type=int, default=4, help="Nombre de vCPU (défaut : 4)."
"--vcpus", type=int, default=2, help="Nombre de vCPU (défaut : 2)."
)
g_vm.add_argument(
"--disk-size",
default="20G",
help="Taille du disque virtuel, ex. 120G (défaut : 20G).",
default=None,
help="Taille du disque virtuel, ex. 120G (défaut : minimum requis "
"par la version Ubuntu, voir la liste ci-dessous).",
)
g_vm.add_argument(
"--disk-dir",
@ -907,10 +917,15 @@ def load_ssh_keys(paths: list[str]) -> list[str]:
def main() -> None:
args = build_parser().parse_args()
codename, default_osinfo = UBUNTU_VERSIONS[args.version]
codename, default_osinfo, min_ram, min_disk = UBUNTU_VERSIONS[args.version]
if args.codename:
codename = args.codename
osinfo = args.osinfo or default_osinfo
# Dimensionnement par défaut = minimum requis par la version (libosinfo).
if args.memory is None:
args.memory = min_ram
if args.disk_size is None:
args.disk_size = min_disk
url = image_url(codename, args.arch)
# Chemin de l'image : déduit automatiquement si non fourni.

View file

@ -812,9 +812,11 @@ class TODO:
print(t("VM name is required!"))
return
version = self._qemu_prompt_version()
memory = input(t("RAM in MB (default: 8192): ")).strip() or "8192"
vcpus = input(t("vCPUs (default: 4): ")).strip() or "4"
disk_size = input(t("Disk size (default: 20G): ")).strip() or "20G"
# Laisser vide => le script applique le minimum requis par la version
# Ubuntu choisie (libosinfo). On n'envoie alors pas le flag.
memory = input(t("RAM in MB (blank = version minimum): ")).strip()
vcpus = input(t("vCPUs (default: 2): ")).strip()
disk_size = input(t("Disk size (blank = version minimum): ")).strip()
default_key = self._qemu_default_ssh_key()
key_hint = default_key or t("none")
@ -849,14 +851,12 @@ class TODO:
parts.append("sudo")
parts.append(script_path)
parts += ["--name", name, "--version", version]
parts += [
"--memory",
memory,
"--vcpus",
vcpus,
"--disk-size",
disk_size,
]
if memory:
parts += ["--memory", memory]
if vcpus:
parts += ["--vcpus", vcpus]
if disk_size:
parts += ["--disk-size", disk_size]
if ssh_key:
parts += ["--ssh-key", ssh_key]
if use_password:

View file

@ -1041,17 +1041,17 @@ TRANSLATIONS = {
"fr": "Nom de la VM : ",
"en": "VM name: ",
},
"RAM in MB (default: 8192): ": {
"fr": "RAM en Mo (défaut : 8192) : ",
"en": "RAM in MB (default: 8192): ",
"RAM in MB (blank = version minimum): ": {
"fr": "RAM en Mo (vide = minimum de la version) : ",
"en": "RAM in MB (blank = version minimum): ",
},
"vCPUs (default: 4): ": {
"fr": "vCPU (défaut : 4) : ",
"en": "vCPUs (default: 4): ",
"vCPUs (default: 2): ": {
"fr": "vCPU (défaut : 2) : ",
"en": "vCPUs (default: 2): ",
},
"Disk size (default: 20G): ": {
"fr": "Taille du disque (défaut : 20G) : ",
"en": "Disk size (default: 20G): ",
"Disk size (blank = version minimum): ": {
"fr": "Taille du disque (vide = minimum de la version) : ",
"en": "Disk size (blank = version minimum): ",
},
"SSH public key path": {
"fr": "Chemin de la clé publique SSH",