[IMP] script todo: réduction disque — proposer d'éteindre la VM et réessayer
Avant, réduire le disque d'une VM allumée affichait seulement « Éteignez la VM » puis abandonnait. Désormais on DEMANDE (o/N) si on veut l'éteindre et réessayer : - _qemu_shutdown_wait : arrêt ACPI gracieux (virsh shutdown), attente jusqu'à « shut off » (timeout 120s), puis propose un arrêt forcé (virsh destroy) si l'arrêt traîne. - _qemu_domname : résout un ID numérique en nom canonique — l'ID disparaît une fois la VM éteinte, le polling doit utiliser le nom. Validé : domname(14) -> erplibre-ubuntu-2004. - Tous les nouveaux prompts affichent la valeur par défaut (o/N). Une fois éteinte, la réduction (qemu-img resize --shrink) se poursuit automatiquement après confirmation du risque. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
4d2b7cea00
commit
03f6205b9e
2 changed files with 78 additions and 2 deletions
|
|
@ -1280,6 +1280,54 @@ class TODO:
|
|||
return ""
|
||||
return res.stdout.strip() if res.returncode == 0 else ""
|
||||
|
||||
@staticmethod
|
||||
def _qemu_domname(name):
|
||||
"""Nom canonique de la VM (si on a fourni un ID numérique, le
|
||||
résout ; sinon renvoie tel quel). Utile car un ID disparaît une
|
||||
fois la VM éteinte."""
|
||||
if not str(name).isdigit():
|
||||
return name
|
||||
try:
|
||||
res = subprocess.run(
|
||||
["sudo", "virsh", "domname", str(name)],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=15,
|
||||
)
|
||||
except (OSError, subprocess.SubprocessError):
|
||||
return name
|
||||
out = res.stdout.strip()
|
||||
return out if res.returncode == 0 and out else name
|
||||
|
||||
def _qemu_shutdown_wait(self, name, timeout=120):
|
||||
"""Arrête la VM proprement (ACPI) et attend qu'elle soit « shut off ».
|
||||
Si l'arrêt gracieux traîne, propose un arrêt forcé (destroy).
|
||||
Renvoie True si la VM est bien éteinte."""
|
||||
name = self._qemu_domname(name)
|
||||
if self._qemu_domstate(name) == "shut off":
|
||||
return True
|
||||
cmd = f"sudo virsh shutdown {shlex.quote(name)}"
|
||||
print(f"{t('Will execute:')} {cmd}")
|
||||
self.execute.exec_command_live(cmd, source_erplibre=False)
|
||||
print(t("Waiting for the VM to shut down..."))
|
||||
deadline = time.time() + timeout
|
||||
while time.time() < deadline:
|
||||
if self._qemu_domstate(name) == "shut off":
|
||||
print(f"✅ {name}: {t('VM is off.')}")
|
||||
return True
|
||||
time.sleep(3)
|
||||
# Arrêt gracieux trop long : proposer un arrêt forcé.
|
||||
if self._is_yes(
|
||||
input(t("Graceful shutdown timed out. Force off (destroy)? "
|
||||
"(y/N): "))
|
||||
):
|
||||
cmd = f"sudo virsh destroy {shlex.quote(name)}"
|
||||
print(f"{t('Will execute:')} {cmd}")
|
||||
self.execute.exec_command_live(cmd, source_erplibre=False)
|
||||
time.sleep(2)
|
||||
return self._qemu_domstate(name) == "shut off"
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def _qemu_main_disk(name):
|
||||
"""Chemin du disque PRINCIPAL (qcow2) de la VM via domblklist. On
|
||||
|
|
@ -1396,8 +1444,16 @@ class TODO:
|
|||
)
|
||||
print(f"⚠ {danger}")
|
||||
if state != "shut off":
|
||||
print(t("Shut the VM off before shrinking (virsh shutdown)."))
|
||||
return
|
||||
if not self._is_yes(
|
||||
input(t("The VM must be off. Shut it down and retry? "
|
||||
"(y/N): "))
|
||||
):
|
||||
print(t("Cancelled."))
|
||||
return
|
||||
if not self._qemu_shutdown_wait(name):
|
||||
print(t("VM is still not off; aborting."))
|
||||
return
|
||||
state = "shut off"
|
||||
if not self._is_yes(
|
||||
input(t("Type y to confirm you understand the risk (y/N): "))
|
||||
):
|
||||
|
|
|
|||
|
|
@ -1420,6 +1420,26 @@ TRANSLATIONS = {
|
|||
"fr": "Impossible de lire la taille actuelle du disque ; abandon.",
|
||||
"en": "Could not read current disk size; aborting.",
|
||||
},
|
||||
"The VM must be off. Shut it down and retry? (y/N): ": {
|
||||
"fr": "La VM doit être éteinte. L'éteindre et réessayer ? (o/N) : ",
|
||||
"en": "The VM must be off. Shut it down and retry? (y/N): ",
|
||||
},
|
||||
"VM is still not off; aborting.": {
|
||||
"fr": "La VM n'est toujours pas éteinte ; abandon.",
|
||||
"en": "VM is still not off; aborting.",
|
||||
},
|
||||
"Waiting for the VM to shut down...": {
|
||||
"fr": "Attente de l'arrêt de la VM…",
|
||||
"en": "Waiting for the VM to shut down...",
|
||||
},
|
||||
"VM is off.": {
|
||||
"fr": "VM éteinte.",
|
||||
"en": "VM is off.",
|
||||
},
|
||||
"Graceful shutdown timed out. Force off (destroy)? (y/N): ": {
|
||||
"fr": "Arrêt gracieux trop long. Forcer l'arrêt (destroy) ? (o/N) : ",
|
||||
"en": "Graceful shutdown timed out. Force off (destroy)? (y/N): ",
|
||||
},
|
||||
"Show advanced info (vCPU, RAM, disk)? (y/N): ": {
|
||||
"fr": "Afficher les infos avancées (vCPU, RAM, disque) ? (o/N) : ",
|
||||
"en": "Show advanced info (vCPU, RAM, disk)? (y/N): ",
|
||||
|
|
|
|||
Loading…
Reference in a new issue