[FIX] qemu: forcer LC_ALL=C sur virsh/sgdisk/… (locale fr cassait l'état des VM)
Sur un hôte en français, « virsh domstate » renvoie « en cours d'exécution » au lieu de « running ». Le test « state == "running" » échouait donc : l'agrandissement à chaud tombait dans la branche « qemu-img resize » (au lieu de « virsh blockresize ») sur une VM ALLUMÉE -> « Failed to get write lock ». On force désormais LC_ALL=C / LANG=C (via _qemu_c_env) sur tous les outils dont on PARSE la sortie, pour avoir l'anglais quelle que soit la locale : virsh domstate/domname/dominfo/domblklist/list, sgdisk -i, dumpe2fs, resize2fs -P (todo.py) et virsh list --all (dashboard). Cela répare aussi, en locale fr, la détection d'état (pause/éteinte), l'analyse des infos avancées (CPU/RAM) et le parsing de la réduction (partition/GPT). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
8be034f25e
commit
ae3745a22a
2 changed files with 23 additions and 4 deletions
|
|
@ -489,6 +489,9 @@ def virsh_domstates() -> dict:
|
||||||
capture_output=True,
|
capture_output=True,
|
||||||
text=True,
|
text=True,
|
||||||
timeout=15,
|
timeout=15,
|
||||||
|
# LC_ALL=C : sortie en ANGLAIS (« running »/« paused »/« shut off »
|
||||||
|
# + en-tête « Id Name State ») quelle que soit la locale de l'hôte.
|
||||||
|
env={**os.environ, "LC_ALL": "C", "LANG": "C"},
|
||||||
)
|
)
|
||||||
except (OSError, subprocess.SubprocessError):
|
except (OSError, subprocess.SubprocessError):
|
||||||
return {}
|
return {}
|
||||||
|
|
|
||||||
|
|
@ -1241,6 +1241,7 @@ class TODO:
|
||||||
capture_output=True,
|
capture_output=True,
|
||||||
text=True,
|
text=True,
|
||||||
timeout=15,
|
timeout=15,
|
||||||
|
env=TODO._qemu_c_env(),
|
||||||
)
|
)
|
||||||
except (OSError, subprocess.SubprocessError):
|
except (OSError, subprocess.SubprocessError):
|
||||||
return 0, 0
|
return 0, 0
|
||||||
|
|
@ -1489,6 +1490,17 @@ class TODO:
|
||||||
# ------------------------------------------------------------------ #
|
# ------------------------------------------------------------------ #
|
||||||
# Redimensionnement du disque d'une VM
|
# Redimensionnement du disque d'une VM
|
||||||
# ------------------------------------------------------------------ #
|
# ------------------------------------------------------------------ #
|
||||||
|
@staticmethod
|
||||||
|
def _qemu_c_env():
|
||||||
|
"""Environnement forçant LC_ALL=C : la sortie des outils (virsh,
|
||||||
|
sgdisk, resize2fs, dumpe2fs…) reste en ANGLAIS quelle que soit la
|
||||||
|
locale de l'hôte. Sinon « running » devient « en cours d'exécution »
|
||||||
|
(fr) et les comparaisons/parsing d'état cassent."""
|
||||||
|
env = dict(os.environ)
|
||||||
|
env["LC_ALL"] = "C"
|
||||||
|
env["LANG"] = "C"
|
||||||
|
return env
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _qemu_domstate(name):
|
def _qemu_domstate(name):
|
||||||
"""État libvirt de la VM (« running », « shut off », …) ou ''."""
|
"""État libvirt de la VM (« running », « shut off », …) ou ''."""
|
||||||
|
|
@ -1498,6 +1510,7 @@ class TODO:
|
||||||
capture_output=True,
|
capture_output=True,
|
||||||
text=True,
|
text=True,
|
||||||
timeout=15,
|
timeout=15,
|
||||||
|
env=TODO._qemu_c_env(),
|
||||||
)
|
)
|
||||||
except (OSError, subprocess.SubprocessError):
|
except (OSError, subprocess.SubprocessError):
|
||||||
return ""
|
return ""
|
||||||
|
|
@ -1516,6 +1529,7 @@ class TODO:
|
||||||
capture_output=True,
|
capture_output=True,
|
||||||
text=True,
|
text=True,
|
||||||
timeout=15,
|
timeout=15,
|
||||||
|
env=TODO._qemu_c_env(),
|
||||||
)
|
)
|
||||||
except (OSError, subprocess.SubprocessError):
|
except (OSError, subprocess.SubprocessError):
|
||||||
return name
|
return name
|
||||||
|
|
@ -1571,6 +1585,7 @@ class TODO:
|
||||||
capture_output=True,
|
capture_output=True,
|
||||||
text=True,
|
text=True,
|
||||||
timeout=15,
|
timeout=15,
|
||||||
|
env=TODO._qemu_c_env(),
|
||||||
)
|
)
|
||||||
except (OSError, subprocess.SubprocessError):
|
except (OSError, subprocess.SubprocessError):
|
||||||
return None
|
return None
|
||||||
|
|
@ -2001,7 +2016,7 @@ class TODO:
|
||||||
info = {"type": "", "uuid": "", "name": ""}
|
info = {"type": "", "uuid": "", "name": ""}
|
||||||
res = subprocess.run(
|
res = subprocess.run(
|
||||||
["sudo", "sgdisk", "-i", n, dev],
|
["sudo", "sgdisk", "-i", n, dev],
|
||||||
capture_output=True, text=True,
|
capture_output=True, text=True, env=TODO._qemu_c_env(),
|
||||||
)
|
)
|
||||||
for line in res.stdout.splitlines():
|
for line in res.stdout.splitlines():
|
||||||
low = line.lower()
|
low = line.lower()
|
||||||
|
|
@ -2017,7 +2032,7 @@ class TODO:
|
||||||
def _qemu_fs_blocksize(part):
|
def _qemu_fs_blocksize(part):
|
||||||
res = subprocess.run(
|
res = subprocess.run(
|
||||||
["sudo", "dumpe2fs", "-h", part],
|
["sudo", "dumpe2fs", "-h", part],
|
||||||
capture_output=True, text=True,
|
capture_output=True, text=True, env=TODO._qemu_c_env(),
|
||||||
)
|
)
|
||||||
for line in res.stdout.splitlines():
|
for line in res.stdout.splitlines():
|
||||||
if line.startswith("Block size:"):
|
if line.startswith("Block size:"):
|
||||||
|
|
@ -2031,7 +2046,7 @@ class TODO:
|
||||||
def _qemu_fs_blocks(part):
|
def _qemu_fs_blocks(part):
|
||||||
res = subprocess.run(
|
res = subprocess.run(
|
||||||
["sudo", "dumpe2fs", "-h", part],
|
["sudo", "dumpe2fs", "-h", part],
|
||||||
capture_output=True, text=True,
|
capture_output=True, text=True, env=TODO._qemu_c_env(),
|
||||||
)
|
)
|
||||||
for line in res.stdout.splitlines():
|
for line in res.stdout.splitlines():
|
||||||
if line.startswith("Block count:"):
|
if line.startswith("Block count:"):
|
||||||
|
|
@ -2046,7 +2061,7 @@ class TODO:
|
||||||
"""Taille minimale (blocs) du FS via « resize2fs -P »."""
|
"""Taille minimale (blocs) du FS via « resize2fs -P »."""
|
||||||
res = subprocess.run(
|
res = subprocess.run(
|
||||||
["sudo", "resize2fs", "-P", part],
|
["sudo", "resize2fs", "-P", part],
|
||||||
capture_output=True, text=True,
|
capture_output=True, text=True, env=TODO._qemu_c_env(),
|
||||||
)
|
)
|
||||||
for tok in res.stdout.replace(":", " ").split():
|
for tok in res.stdout.replace(":", " ").split():
|
||||||
if tok.isdigit():
|
if tok.isdigit():
|
||||||
|
|
@ -2454,6 +2469,7 @@ class TODO:
|
||||||
capture_output=True,
|
capture_output=True,
|
||||||
text=True,
|
text=True,
|
||||||
timeout=15,
|
timeout=15,
|
||||||
|
env=self._qemu_c_env(),
|
||||||
)
|
)
|
||||||
except (OSError, subprocess.SubprocessError):
|
except (OSError, subprocess.SubprocessError):
|
||||||
continue
|
continue
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue